isaacpittman-hitachi / rpms / openssl

Forked from rpms/openssl 2 years ago
Clone
Blob Blame History Raw
diff -up openssl-1.0.2i/apps/speed.c.fips openssl-1.0.2i/apps/speed.c
--- openssl-1.0.2i/apps/speed.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/apps/speed.c	2016-09-22 13:35:57.007220767 +0200
@@ -197,7 +197,6 @@
 #  ifdef OPENSSL_DOING_MAKEDEPEND
 #   undef AES_set_encrypt_key
 #   undef AES_set_decrypt_key
-#   undef DES_set_key_unchecked
 #  endif
 #  define BF_set_key      private_BF_set_key
 #  define CAST_set_key    private_CAST_set_key
@@ -205,7 +204,6 @@
 #  define SEED_set_key    private_SEED_set_key
 #  define RC2_set_key     private_RC2_set_key
 #  define RC4_set_key     private_RC4_set_key
-#  define DES_set_key_unchecked   private_DES_set_key_unchecked
 #  define AES_set_encrypt_key     private_AES_set_encrypt_key
 #  define AES_set_decrypt_key     private_AES_set_decrypt_key
 #  define Camellia_set_key        private_Camellia_set_key
@@ -974,7 +972,12 @@ int MAIN(int argc, char **argv)
 # endif
 # ifndef OPENSSL_NO_RSA
         if (strcmp(*argv, "rsa") == 0) {
-            rsa_doit[R_RSA_512] = 1;
+#  ifdef OPENSSL_FIPS
+            if (!FIPS_mode())
+#  endif
+            {
+                rsa_doit[R_RSA_512] = 1;
+            }
             rsa_doit[R_RSA_1024] = 1;
             rsa_doit[R_RSA_2048] = 1;
             rsa_doit[R_RSA_4096] = 1;
@@ -982,7 +985,12 @@ int MAIN(int argc, char **argv)
 # endif
 # ifndef OPENSSL_NO_DSA
         if (strcmp(*argv, "dsa") == 0) {
-            dsa_doit[R_DSA_512] = 1;
+#  ifdef OPENSSL_FIPS
+            if (!FIPS_mode())
+#  endif
+            {
+                dsa_doit[R_DSA_512] = 1;
+            }
             dsa_doit[R_DSA_1024] = 1;
             dsa_doit[R_DSA_2048] = 1;
         } else
@@ -1233,13 +1241,19 @@ int MAIN(int argc, char **argv)
 
     if (j == 0) {
         for (i = 0; i < ALGOR_NUM; i++) {
-            if (i != D_EVP)
+            if (i != D_EVP &&
+                (!FIPS_mode() || (i != D_WHIRLPOOL &&
+                                  i != D_MD2 && i != D_MD4 &&
+                                  i != D_MD5 && i != D_MDC2 &&
+                                  i != D_RMD160)))
                 doit[i] = 1;
         }
         for (i = 0; i < RSA_NUM; i++)
-            rsa_doit[i] = 1;
+            if (!FIPS_mode() || i != R_RSA_512)
+                rsa_doit[i] = 1;
         for (i = 0; i < DSA_NUM; i++)
-            dsa_doit[i] = 1;
+            if (!FIPS_mode() || i != R_DSA_512)
+                dsa_doit[i] = 1;
 # ifndef OPENSSL_NO_ECDSA
         for (i = 0; i < EC_NUM; i++)
             ecdsa_doit[i] = 1;
@@ -1299,30 +1313,46 @@ int MAIN(int argc, char **argv)
     AES_set_encrypt_key(key32, 256, &aes_ks3);
 # endif
 # ifndef OPENSSL_NO_CAMELLIA
-    Camellia_set_key(key16, 128, &camellia_ks1);
-    Camellia_set_key(ckey24, 192, &camellia_ks2);
-    Camellia_set_key(ckey32, 256, &camellia_ks3);
+    if (doit[D_CBC_128_CML] || doit[D_CBC_192_CML] || doit[D_CBC_256_CML]) {
+        Camellia_set_key(key16, 128, &camellia_ks1);
+        Camellia_set_key(ckey24, 192, &camellia_ks2);
+        Camellia_set_key(ckey32, 256, &camellia_ks3);
+    }
 # endif
 # ifndef OPENSSL_NO_IDEA
-    idea_set_encrypt_key(key16, &idea_ks);
+    if (doit[D_CBC_IDEA]) {
+        idea_set_encrypt_key(key16, &idea_ks);
+    }
 # endif
 # ifndef OPENSSL_NO_SEED
-    SEED_set_key(key16, &seed_ks);
+    if (doit[D_CBC_SEED]) {
+        SEED_set_key(key16, &seed_ks);
+    }
 # endif
 # ifndef OPENSSL_NO_RC4
-    RC4_set_key(&rc4_ks, 16, key16);
+    if (doit[D_RC4]) {
+        RC4_set_key(&rc4_ks, 16, key16);
+    }
 # endif
 # ifndef OPENSSL_NO_RC2
-    RC2_set_key(&rc2_ks, 16, key16, 128);
+    if (doit[D_CBC_RC2]) {
+        RC2_set_key(&rc2_ks, 16, key16, 128);
+    }
 # endif
 # ifndef OPENSSL_NO_RC5
-    RC5_32_set_key(&rc5_ks, 16, key16, 12);
+    if (doit[D_CBC_RC5]) {
+        RC5_32_set_key(&rc5_ks, 16, key16, 12);
+    }
 # endif
 # ifndef OPENSSL_NO_BF
-    BF_set_key(&bf_ks, 16, key16);
+    if (doit[D_CBC_BF]) {
+        BF_set_key(&bf_ks, 16, key16);
+    }
 # endif
 # ifndef OPENSSL_NO_CAST
-    CAST_set_key(&cast_ks, 16, key16);
+    if (doit[D_CBC_CAST]) {
+        CAST_set_key(&cast_ks, 16, key16);
+    }
 # endif
 # ifndef OPENSSL_NO_RSA
     memset(rsa_c, 0, sizeof(rsa_c));
@@ -1605,6 +1635,7 @@ int MAIN(int argc, char **argv)
         HMAC_CTX hctx;
 
         HMAC_CTX_init(&hctx);
+        HMAC_CTX_set_flags(&hctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
         HMAC_Init_ex(&hctx, (unsigned char *)"This is a key...",
                      16, EVP_md5(), NULL);
 
diff -up openssl-1.0.2i/Configure.fips openssl-1.0.2i/Configure
--- openssl-1.0.2i/Configure.fips	2016-09-22 13:35:56.993220444 +0200
+++ openssl-1.0.2i/Configure	2016-09-22 13:35:57.008220790 +0200
@@ -1067,11 +1067,6 @@ if (defined($disabled{"md5"}) || defined
 	$disabled{"ssl2"} = "forced";
 	}
 
-if ($fips && $fipslibdir eq "")
-	{
-	$fipslibdir = $fipsdir . "/lib/";
-	}
-
 # RSAX ENGINE sets default non-FIPS RSA method.
 if ($fips)
 	{
@@ -1556,7 +1551,6 @@ $cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($b
 if ($fips)
 	{
 	$openssl_other_defines.="#define OPENSSL_FIPS\n";
-	$cflags .= " -I\$(FIPSDIR)/include";
 	}
 
 $cpuid_obj="mem_clr.o"	unless ($cpuid_obj =~ /\.o$/);
@@ -1768,9 +1762,12 @@ while (<IN>)
 
 	s/^FIPSDIR=.*/FIPSDIR=$fipsdir/;
 	s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/;
-	s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips;
 	s/^BASEADDR=.*/BASEADDR=$baseaddr/;
 
+	if ($fips)
+		{
+		s/^FIPS=.*/FIPS=yes/;
+		}
 	s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/;
 	s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/;
 	s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared);
diff -up openssl-1.0.2i/crypto/aes/aes_misc.c.fips openssl-1.0.2i/crypto/aes/aes_misc.c
--- openssl-1.0.2i/crypto/aes/aes_misc.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/aes/aes_misc.c	2016-09-22 13:35:57.008220790 +0200
@@ -70,17 +70,11 @@ const char *AES_options(void)
 int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
                         AES_KEY *key)
 {
-#ifdef OPENSSL_FIPS
-    fips_cipher_abort(AES);
-#endif
     return private_AES_set_encrypt_key(userKey, bits, key);
 }
 
 int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
                         AES_KEY *key)
 {
-#ifdef OPENSSL_FIPS
-    fips_cipher_abort(AES);
-#endif
     return private_AES_set_decrypt_key(userKey, bits, key);
 }
diff -up openssl-1.0.2i/crypto/cmac/cmac.c.fips openssl-1.0.2i/crypto/cmac/cmac.c
--- openssl-1.0.2i/crypto/cmac/cmac.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/cmac/cmac.c	2016-09-22 13:35:57.008220790 +0200
@@ -105,12 +105,6 @@ CMAC_CTX *CMAC_CTX_new(void)
 
 void CMAC_CTX_cleanup(CMAC_CTX *ctx)
 {
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !ctx->cctx.engine) {
-        FIPS_cmac_ctx_cleanup(ctx);
-        return;
-    }
-#endif
     EVP_CIPHER_CTX_cleanup(&ctx->cctx);
     OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
     OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
@@ -160,20 +154,6 @@ int CMAC_Init(CMAC_CTX *ctx, const void
             EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
             return 0;
         }
-
-        /* Switch to FIPS cipher implementation if possible */
-        if (cipher != NULL) {
-            const EVP_CIPHER *fcipher;
-            fcipher = FIPS_get_cipherbynid(EVP_CIPHER_nid(cipher));
-            if (fcipher != NULL)
-                cipher = fcipher;
-        }
-        /*
-         * Other algorithm blocking will be done in FIPS_cmac_init, via
-         * FIPS_cipherinit().
-         */
-        if (!impl && !ctx->cctx.engine)
-            return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
     }
 #endif
     /* All zeros means restart */
@@ -219,10 +199,6 @@ int CMAC_Update(CMAC_CTX *ctx, const voi
 {
     const unsigned char *data = in;
     size_t bl;
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !ctx->cctx.engine)
-        return FIPS_cmac_update(ctx, in, dlen);
-#endif
     if (ctx->nlast_block == -1)
         return 0;
     if (dlen == 0)
@@ -262,10 +238,6 @@ int CMAC_Update(CMAC_CTX *ctx, const voi
 int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
 {
     int i, bl, lb;
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !ctx->cctx.engine)
-        return FIPS_cmac_final(ctx, out, poutlen);
-#endif
     if (ctx->nlast_block == -1)
         return 0;
     bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
diff -up openssl-1.0.2i/crypto/crypto.h.fips openssl-1.0.2i/crypto/crypto.h
--- openssl-1.0.2i/crypto/crypto.h.fips	2016-09-22 13:35:56.890218070 +0200
+++ openssl-1.0.2i/crypto/crypto.h	2016-09-22 13:35:57.008220790 +0200
@@ -600,24 +600,29 @@ int FIPS_mode_set(int r);
 void OPENSSL_init(void);
 
 # define fips_md_init(alg) fips_md_init_ctx(alg, alg)
+# define nonfips_md_init(alg) nonfips_md_init_ctx(alg, alg)
+# define fips_md_init_ctx(alg, cx) \
+        int alg##_Init(cx##_CTX *c)
 
 # ifdef OPENSSL_FIPS
-#  define fips_md_init_ctx(alg, cx) \
+#  define nonfips_md_init_ctx(alg, cx) \
         int alg##_Init(cx##_CTX *c) \
         { \
         if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
-                "Low level API call to digest " #alg " forbidden in FIPS mode!"); \
+                "Digest " #alg " forbidden in FIPS mode!"); \
         return private_##alg##_Init(c); \
         } \
         int private_##alg##_Init(cx##_CTX *c)
 
 #  define fips_cipher_abort(alg) \
         if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
-                "Low level API call to cipher " #alg " forbidden in FIPS mode!")
+                "Cipher " #alg " forbidden in FIPS mode!")
+
+/* die if FIPS selftest failed */
+void FIPS_selftest_check(void);
 
 # else
-#  define fips_md_init_ctx(alg, cx) \
-        int alg##_Init(cx##_CTX *c)
+#  define nonfips_md_init_ctx(alg, cx) fips_md_init_ctx(alg, cx)
 #  define fips_cipher_abort(alg) while(0)
 # endif
 
@@ -637,6 +642,9 @@ int CRYPTO_memcmp(const volatile void *a
  */
 void ERR_load_CRYPTO_strings(void);
 
+# define OPENSSL_HAVE_INIT       1
+void OPENSSL_init_library(void);
+
 /* Error codes for the CRYPTO functions. */
 
 /* Function codes. */
diff -up openssl-1.0.2i/crypto/des/des.h.fips openssl-1.0.2i/crypto/des/des.h
--- openssl-1.0.2i/crypto/des/des.h.fips	2016-09-22 13:35:56.918218715 +0200
+++ openssl-1.0.2i/crypto/des/des.h	2016-09-22 13:35:57.008220790 +0200
@@ -231,10 +231,6 @@ int DES_set_key(const_DES_cblock *key, D
 int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
 int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);
 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
-# ifdef OPENSSL_FIPS
-void private_DES_set_key_unchecked(const_DES_cblock *key,
-                                   DES_key_schedule *schedule);
-# endif
 void DES_string_to_key(const char *str, DES_cblock *key);
 void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2);
 void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
diff -up openssl-1.0.2i/crypto/des/set_key.c.fips openssl-1.0.2i/crypto/des/set_key.c
--- openssl-1.0.2i/crypto/des/set_key.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/des/set_key.c	2016-09-22 13:35:57.008220790 +0200
@@ -359,15 +359,6 @@ int DES_set_key_checked(const_DES_cblock
 }
 
 void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
-#ifdef OPENSSL_FIPS
-{
-    fips_cipher_abort(DES);
-    private_DES_set_key_unchecked(key, schedule);
-}
-
-void private_DES_set_key_unchecked(const_DES_cblock *key,
-                                   DES_key_schedule *schedule)
-#endif
 {
     static const int shifts2[16] =
         { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
diff -up openssl-1.0.2i/crypto/dh/dh_gen.c.fips openssl-1.0.2i/crypto/dh/dh_gen.c
--- openssl-1.0.2i/crypto/dh/dh_gen.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dh/dh_gen.c	2016-09-22 13:35:57.009220813 +0200
@@ -85,10 +85,6 @@ int DH_generate_parameters_ex(DH *ret, i
 #endif
     if (ret->meth->generate_params)
         return ret->meth->generate_params(ret, prime_len, generator, cb);
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode())
-        return FIPS_dh_generate_parameters_ex(ret, prime_len, generator, cb);
-#endif
     return dh_builtin_genparams(ret, prime_len, generator, cb);
 }
 
@@ -126,6 +122,18 @@ static int dh_builtin_genparams(DH *ret,
     int g, ok = -1;
     BN_CTX *ctx = NULL;
 
+#ifdef OPENSSL_FIPS
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS, FIPS_R_FIPS_SELFTEST_FAILED);
+        return 0;
+    }
+
+    if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) {
+        DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL);
+        goto err;
+    }
+#endif
+
     ctx = BN_CTX_new();
     if (ctx == NULL)
         goto err;
diff -up openssl-1.0.2i/crypto/dh/dh.h.fips openssl-1.0.2i/crypto/dh/dh.h
--- openssl-1.0.2i/crypto/dh/dh.h.fips	2016-09-22 13:35:56.863217447 +0200
+++ openssl-1.0.2i/crypto/dh/dh.h	2016-09-22 13:35:57.009220813 +0200
@@ -77,6 +77,8 @@
 #  define OPENSSL_DH_MAX_MODULUS_BITS    10000
 # endif
 
+# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
+
 # define DH_FLAG_CACHE_MONT_P     0x01
 
 /*
diff -up openssl-1.0.2i/crypto/dh/dh_key.c.fips openssl-1.0.2i/crypto/dh/dh_key.c
--- openssl-1.0.2i/crypto/dh/dh_key.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dh/dh_key.c	2016-09-22 13:35:57.009220813 +0200
@@ -61,6 +61,9 @@
 #include <openssl/bn.h>
 #include <openssl/rand.h>
 #include <openssl/dh.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
 
 static int generate_key(DH *dh);
 static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
@@ -97,7 +100,7 @@ int DH_compute_key(unsigned char *key, c
 int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
 {
     int rv, pad;
-    rv = dh->meth->compute_key(key, pub_key, dh);
+    rv = DH_compute_key(key, pub_key, dh);
     if (rv <= 0)
         return rv;
     pad = BN_num_bytes(dh->p) - rv;
@@ -115,7 +118,7 @@ static DH_METHOD dh_ossl = {
     dh_bn_mod_exp,
     dh_init,
     dh_finish,
-    0,
+    DH_FLAG_FIPS_METHOD,
     NULL,
     NULL
 };
@@ -134,6 +137,14 @@ static int generate_key(DH *dh)
     BN_MONT_CTX *mont = NULL;
     BIGNUM *pub_key = NULL, *priv_key = NULL;
 
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode()
+        && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) {
+        DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
+        return 0;
+    }
+#endif
+
     ctx = BN_CTX_new();
     if (ctx == NULL)
         goto err;
@@ -217,6 +228,13 @@ static int compute_key(unsigned char *ke
         DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
         goto err;
     }
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode()
+        && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) {
+        DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
+        goto err;
+    }
+#endif
 
     ctx = BN_CTX_new();
     if (ctx == NULL)
@@ -277,6 +295,9 @@ static int dh_bn_mod_exp(const DH *dh, B
 
 static int dh_init(DH *dh)
 {
+#ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+#endif
     dh->flags |= DH_FLAG_CACHE_MONT_P;
     return (1);
 }
diff -up openssl-1.0.2i/crypto/dh/dh_lib.c.fips openssl-1.0.2i/crypto/dh/dh_lib.c
--- openssl-1.0.2i/crypto/dh/dh_lib.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dh/dh_lib.c	2016-09-22 13:35:57.009220813 +0200
@@ -80,14 +80,7 @@ void DH_set_default_method(const DH_METH
 const DH_METHOD *DH_get_default_method(void)
 {
     if (!default_DH_method) {
-#ifdef OPENSSL_FIPS
-        if (FIPS_mode())
-            return FIPS_dh_openssl();
-        else
-            return DH_OpenSSL();
-#else
         default_DH_method = DH_OpenSSL();
-#endif
     }
     return default_DH_method;
 }
diff -up openssl-1.0.2i/crypto/dsa/dsa_err.c.fips openssl-1.0.2i/crypto/dsa/dsa_err.c
--- openssl-1.0.2i/crypto/dsa/dsa_err.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa_err.c	2016-09-22 13:35:57.009220813 +0200
@@ -74,6 +74,8 @@ static ERR_STRING_DATA DSA_str_functs[]
     {ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"},
     {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"},
     {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"},
+    {ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN), "dsa_builtin_keygen"},
+    {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "dsa_builtin_paramgen"},
     {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"},
     {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"},
     {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"},
@@ -109,6 +111,8 @@ static ERR_STRING_DATA DSA_str_reasons[]
     {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"},
     {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"},
     {ERR_REASON(DSA_R_INVALID_PARAMETERS), "invalid parameters"},
+    {ERR_REASON(DSA_R_KEY_SIZE_INVALID), "key size invalid"},
+    {ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL), "key size too small"},
     {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"},
     {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"},
     {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
diff -up openssl-1.0.2i/crypto/dsa/dsa_gen.c.fips openssl-1.0.2i/crypto/dsa/dsa_gen.c
--- openssl-1.0.2i/crypto/dsa/dsa_gen.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa_gen.c	2016-09-22 13:42:54.389840662 +0200
@@ -91,6 +91,16 @@
 #  include <openssl/fips.h>
 # endif
 
+# ifndef OPENSSL_FIPS
+static int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
+                                const EVP_MD *evpmd, unsigned char *seed,
+                                int seed_len, BIGNUM **p_ret, BIGNUM **q_ret,
+                                int *counter_ret, BN_GENCB *cb);
+static int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q,
+                               BIGNUM **g_ret, unsigned long *h_ret,
+                               BN_GENCB *cb);
+# endif
+
 int DSA_generate_parameters_ex(DSA *ret, int bits,
                                const unsigned char *seed_in, int seed_len,
                                int *counter_ret, unsigned long *h_ret,
@@ -106,83 +116,146 @@ int DSA_generate_parameters_ex(DSA *ret,
     if (ret->meth->dsa_paramgen)
         return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
                                        counter_ret, h_ret, cb);
-# ifdef OPENSSL_FIPS
-    else if (FIPS_mode()) {
-        return FIPS_dsa_generate_parameters_ex(ret, bits,
-                                               seed_in, seed_len,
-                                               counter_ret, h_ret, cb);
-    }
-# endif
     else {
         const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
         size_t qbits = EVP_MD_size(evpmd) * 8;
 
         return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
-                                    seed_in, seed_len, NULL, counter_ret,
+                                    seed_in, seed_len, counter_ret,
                                     h_ret, cb);
     }
 }
 
+# ifdef OPENSSL_FIPS
+int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+                              const EVP_MD *evpmd,
+                              const unsigned char *seed_in, size_t seed_len,
+                              int *counter_ret, unsigned long *h_ret,
+                              BN_GENCB *cb)
+{
+    return dsa_builtin_paramgen(ret, bits, qbits,
+                                evpmd, seed_in, seed_len,
+                                counter_ret, h_ret, cb);
+}
+# endif
+
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                          const EVP_MD *evpmd, const unsigned char *seed_in,
-                         size_t seed_len, unsigned char *seed_out,
+                         size_t seed_len,
                          int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
 {
     int ok = 0;
     unsigned char seed[SHA256_DIGEST_LENGTH];
+    BIGNUM *g = NULL, *q = NULL, *p = NULL;
+    size_t qsize = qbits >> 3;
+    BN_CTX *ctx = NULL;
+    
+# ifdef OPENSSL_FIPS
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, FIPS_R_FIPS_SELFTEST_FAILED);
+        goto err;
+    }
+
+    if (FIPS_module_mode() &&
+        (bits != 1024 || qbits != 160) &&
+        (bits != 2048 || qbits != 224) &&
+        (bits != 2048 || qbits != 256) && (bits != 3072 || qbits != 256)) {
+        DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_INVALID);
+        goto err;
+    }
+# endif
+    if (seed_len && (seed_len < (size_t)qsize))
+        seed_in = NULL;         /* seed buffer too small -- ignore */
+    if (seed_len > sizeof(seed))
+        seed_len = sizeof(seed); /* App. 2.2 of FIPS PUB 186 allows larger SEED,
+                                  * but our internal buffers are restricted to 256 bits*/
+    if (seed_in != NULL)
+        memcpy(seed, seed_in, seed_len);
+    else
+        seed_len = 0;
+        
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+ 
+    BN_CTX_start(ctx);
+ 
+    if (!FIPS_dsa_generate_pq(ctx, bits, qbits, evpmd,
+                              seed, seed_len, &p, &q, counter_ret, cb))
+        goto err;
+ 
+    if (!FIPS_dsa_generate_g(ctx, p, q, &g, h_ret, cb))
+        goto err;
+ 
+    ok = 1;
+ err:
+    if (ok) {
+        if (ret->p) {
+            BN_free(ret->p);
+            ret->p = NULL;
+        }
+        if (ret->q) {
+            BN_free(ret->q);
+            ret->q = NULL;
+        }
+        if (ret->g) {
+            BN_free(ret->g);
+            ret->g = NULL;
+        }
+        ret->p = BN_dup(p);
+        ret->q = BN_dup(q);
+        ret->g = BN_dup(g);
+        if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
+            ok = 0;
+    }
+    if (ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    return ok;
+}
+
+# ifndef OPENSSL_FIPS
+static
+# endif
+int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
+                         const EVP_MD *evpmd, unsigned char *seed,
+                         int seed_len, BIGNUM **p_ret, BIGNUM **q_ret,
+                         int *counter_ret, BN_GENCB *cb)
+{
+    int ok = 0;
     unsigned char md[SHA256_DIGEST_LENGTH];
-    unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
+    unsigned char buf[SHA256_DIGEST_LENGTH];
     BIGNUM *r0, *W, *X, *c, *test;
-    BIGNUM *g = NULL, *q = NULL, *p = NULL;
-    BN_MONT_CTX *mont = NULL;
-    int i, k, n = 0, m = 0, qsize = qbits >> 3;
+    BIGNUM *q = NULL, *p = NULL;
+    int i, k, b, n = 0, m = 0, qsize = qbits >> 3;
     int counter = 0;
     int r = 0;
-    BN_CTX *ctx = NULL;
-    unsigned int h = 2;
 
     if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
         qsize != SHA256_DIGEST_LENGTH)
         /* invalid q size */
         return 0;
 
-    if (evpmd == NULL)
-        /* use SHA1 as default */
+    if (evpmd == NULL) {
+        if (qbits <= 160)
         evpmd = EVP_sha1();
+        else if (qbits <= 224)
+            evpmd = EVP_sha224();
+        else
+            evpmd = EVP_sha256();
+    }
 
     if (bits < 512)
         bits = 512;
 
     bits = (bits + 63) / 64 * 64;
 
-    /*
-     * NB: seed_len == 0 is special case: copy generated seed to seed_in if
-     * it is not NULL.
-     */
-    if (seed_len && (seed_len < (size_t)qsize))
-        seed_in = NULL;         /* seed buffer too small -- ignore */
-    if (seed_len > (size_t)qsize)
-        seed_len = qsize;       /* App. 2.2 of FIPS PUB 186 allows larger
-                                 * SEED, but our internal buffers are
-                                 * restricted to 160 bits */
-    if (seed_in != NULL)
-        memcpy(seed, seed_in, seed_len);
-
-    if ((mont = BN_MONT_CTX_new()) == NULL)
-        goto err;
-
-    if ((ctx = BN_CTX_new()) == NULL)
-        goto err;
-
-    BN_CTX_start(ctx);
-
     r0 = BN_CTX_get(ctx);
-    g = BN_CTX_get(ctx);
     W = BN_CTX_get(ctx);
-    q = BN_CTX_get(ctx);
+    *q_ret = q = BN_CTX_get(ctx);
     X = BN_CTX_get(ctx);
     c = BN_CTX_get(ctx);
-    p = BN_CTX_get(ctx);
+    *p_ret = p = BN_CTX_get(ctx);
     test = BN_CTX_get(ctx);
 
     if (test == NULL)
@@ -191,15 +264,20 @@ int dsa_builtin_paramgen(DSA *ret, size_
     if (!BN_lshift(test, BN_value_one(), bits - 1))
         goto err;
 
+    /* step 3 n = \lceil bits / qbits \rceil - 1 */
+    n = (bits + qbits - 1) / qbits - 1;
+    /* step 4 b = bits - 1 - n * qbits */
+    b = bits - 1 - n * qbits;
+
     for (;;) {
         for (;;) {              /* find q */
             int seed_is_random;
 
-            /* step 1 */
+            /* step 5 generate seed */
             if (!BN_GENCB_call(cb, 0, m++))
                 goto err;
 
-            if (!seed_len || !seed_in) {
+            if (!seed_len) {
                 if (RAND_bytes(seed, qsize) <= 0)
                     goto err;
                 seed_is_random = 1;
@@ -209,29 +287,18 @@ int dsa_builtin_paramgen(DSA *ret, size_
                                  * be bad */
             }
             memcpy(buf, seed, qsize);
-            memcpy(buf2, seed, qsize);
-            /* precompute "SEED + 1" for step 7: */
-            for (i = qsize - 1; i >= 0; i--) {
-                buf[i]++;
-                if (buf[i] != 0)
-                    break;
-            }
 
-            /* step 2 */
+            /* step 6 U = hash(seed) */
             if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
                 goto err;
-            if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
-                goto err;
-            for (i = 0; i < qsize; i++)
-                md[i] ^= buf2[i];
 
-            /* step 3 */
+            /* step 7 q = 2^(qbits-1) + U + 1 - (U mod 2) */
             md[0] |= 0x80;
             md[qsize - 1] |= 0x01;
             if (!BN_bin2bn(md, qsize, q))
                 goto err;
 
-            /* step 4 */
+            /* step 8 test for prime (64 round of Rabin-Miller) */
             r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
                                         seed_is_random, cb);
             if (r > 0)
@@ -239,8 +306,6 @@ int dsa_builtin_paramgen(DSA *ret, size_
             if (r != 0)
                 goto err;
 
-            /* do a callback call */
-            /* step 5 */
         }
 
         if (!BN_GENCB_call(cb, 2, 0))
@@ -248,19 +313,16 @@ int dsa_builtin_paramgen(DSA *ret, size_
         if (!BN_GENCB_call(cb, 3, 0))
             goto err;
 
-        /* step 6 */
+        /* step 11 */
         counter = 0;
-        /* "offset = 2" */
-
-        n = (bits - 1) / 160;
+        /* "offset = 1" */
 
         for (;;) {
             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
                 goto err;
 
-            /* step 7 */
+            /* step 11.1, 11.2 obtain W */
             BN_zero(W);
-            /* now 'buf' contains "SEED + offset - 1" */
             for (k = 0; k <= n; k++) {
                 /*
                  * obtain "SEED + offset + k" by incrementing:
@@ -274,36 +336,37 @@ int dsa_builtin_paramgen(DSA *ret, size_
                 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
                     goto err;
 
-                /* step 8 */
                 if (!BN_bin2bn(md, qsize, r0))
                     goto err;
-                if (!BN_lshift(r0, r0, (qsize << 3) * k))
+                if (k == n)
+                    BN_mask_bits(r0, b);
+                if (!BN_lshift(r0, r0, qbits * k))
                     goto err;
                 if (!BN_add(W, W, r0))
                     goto err;
             }
 
-            /* more of step 8 */
-            if (!BN_mask_bits(W, bits - 1))
-                goto err;
+            /* step 11.3 X = W + 2^(L-1) */
             if (!BN_copy(X, W))
                 goto err;
             if (!BN_add(X, X, test))
                 goto err;
 
-            /* step 9 */
+            /* step 11.4 c = X mod 2*q */
             if (!BN_lshift1(r0, q))
                 goto err;
             if (!BN_mod(c, X, r0, ctx))
                 goto err;
+
+            /* step 11.5 p = X - (c - 1) */
             if (!BN_sub(r0, c, BN_value_one()))
                 goto err;
             if (!BN_sub(p, X, r0))
                 goto err;
 
-            /* step 10 */
+            /* step 11.6 */
             if (BN_cmp(p, test) >= 0) {
-                /* step 11 */
+                /* step 11.7 */
                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
                 if (r > 0)
                     goto end;   /* found it */
@@ -311,12 +374,12 @@ int dsa_builtin_paramgen(DSA *ret, size_
                     goto err;
             }
 
-            /* step 13 */
+            /* step 11.9 */
             counter++;
             /* "offset = offset + n + 1" */
 
-            /* step 14 */
-            if (counter >= 4096)
+            /* step 12 */
+            if (counter >= 4 * bits)
                 break;
         }
     }
@@ -324,7 +387,33 @@ int dsa_builtin_paramgen(DSA *ret, size_
     if (!BN_GENCB_call(cb, 2, 1))
         goto err;
 
-    /* We now need to generate g */
+    ok = 1;
+ err:
+    if (ok) {
+        if (counter_ret != NULL)
+            *counter_ret = counter;
+    }
+    return ok;
+}
+
+# ifndef OPENSSL_FIPS
+static
+# endif
+int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q,
+                        BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb)
+{
+    int ok = 0;
+    BIGNUM *r0, *test, *g = NULL;
+    BN_MONT_CTX *mont;
+    unsigned int h = 2;
+
+    if ((mont = BN_MONT_CTX_new()) == NULL)
+        goto err;
+
+    r0 = BN_CTX_get(ctx);
+    *g_ret = g = BN_CTX_get(ctx);
+    test = BN_CTX_get(ctx);
+
     /* Set r0=(p-1)/q */
     if (!BN_sub(test, p, BN_value_one()))
         goto err;
@@ -353,46 +442,14 @@ int dsa_builtin_paramgen(DSA *ret, size_
     ok = 1;
  err:
     if (ok) {
-        if (ret->p)
-            BN_free(ret->p);
-        if (ret->q)
-            BN_free(ret->q);
-        if (ret->g)
-            BN_free(ret->g);
-        ret->p = BN_dup(p);
-        ret->q = BN_dup(q);
-        ret->g = BN_dup(g);
-        if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
-            ok = 0;
-            goto err;
-        }
-        if (counter_ret != NULL)
-            *counter_ret = counter;
         if (h_ret != NULL)
             *h_ret = h;
-        if (seed_out)
-            memcpy(seed_out, seed, qsize);
-    }
-    if (ctx) {
-        BN_CTX_end(ctx);
-        BN_CTX_free(ctx);
     }
     if (mont != NULL)
         BN_MONT_CTX_free(mont);
     return ok;
 }
 
-# ifdef OPENSSL_FIPS
-#  undef fips_dsa_builtin_paramgen2
-extern int fips_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
-                                      const EVP_MD *evpmd,
-                                      const unsigned char *seed_in,
-                                      size_t seed_len, int idx,
-                                      unsigned char *seed_out,
-                                      int *counter_ret, unsigned long *h_ret,
-                                      BN_GENCB *cb);
-# endif
-
 /*
  * This is a parameter generation algorithm for the DSA2 algorithm as
  * described in FIPS 186-3.
@@ -418,14 +475,6 @@ int dsa_builtin_paramgen2(DSA *ret, size
     EVP_MD_CTX mctx;
     unsigned int h = 2;
 
-# ifdef OPENSSL_FIPS
-
-    if (FIPS_mode())
-        return fips_dsa_builtin_paramgen2(ret, L, N, evpmd,
-                                          seed_in, seed_len, idx,
-                                          seed_out, counter_ret, h_ret, cb);
-# endif
-
     EVP_MD_CTX_init(&mctx);
 
     if (evpmd == NULL) {
diff -up openssl-1.0.2i/crypto/dsa/dsa.h.fips openssl-1.0.2i/crypto/dsa/dsa.h
--- openssl-1.0.2i/crypto/dsa/dsa.h.fips	2016-09-22 13:35:56.789215742 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa.h	2016-09-22 13:35:57.010220836 +0200
@@ -88,6 +88,8 @@
 #  define OPENSSL_DSA_MAX_MODULUS_BITS   10000
 # endif
 
+# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024
+
 # define DSA_FLAG_CACHE_MONT_P   0x01
 /*
  * new with 0.9.7h; the built-in DSA implementation now uses constant time
@@ -265,6 +267,20 @@ int DSA_print_fp(FILE *bp, const DSA *x,
 DH *DSA_dup_DH(const DSA *r);
 # endif
 
+# ifdef OPENSSL_FIPS
+int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+                              const EVP_MD *evpmd,
+                              const unsigned char *seed_in,
+                              size_t seed_len, int *counter_ret,
+                              unsigned long *h_ret, BN_GENCB *cb);
+int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
+                         const EVP_MD *evpmd, unsigned char *seed,
+                         int seed_len, BIGNUM **p_ret, BIGNUM **q_ret,
+                         int *counter_ret, BN_GENCB *cb);
+int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, BIGNUM **g_ret,
+                            unsigned long *h_ret, BN_GENCB *cb);
+# endif
+
 # define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
         EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
                                 EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
@@ -287,11 +303,14 @@ void ERR_load_DSA_strings(void);
 # define DSA_F_DO_DSA_PRINT                               104
 # define DSA_F_DSAPARAMS_PRINT                            100
 # define DSA_F_DSAPARAMS_PRINT_FP                         101
-# define DSA_F_DSA_BUILTIN_PARAMGEN2                      126
+# define DSA_F_DSA_BUILTIN_KEYGEN                         124
+# define DSA_F_DSA_BUILTIN_PARAMGEN                       123
+# define DSA_F_DSA_BUILTIN_PARAMGEN2                      226
 # define DSA_F_DSA_DO_SIGN                                112
 # define DSA_F_DSA_DO_VERIFY                              113
-# define DSA_F_DSA_GENERATE_KEY                           124
-# define DSA_F_DSA_GENERATE_PARAMETERS_EX                 123
+# define DSA_F_DSA_GENERATE_KEY                           126
+# define DSA_F_DSA_GENERATE_PARAMETERS_EX                 127
+# define DSA_F_DSA_GENERATE_PARAMETERS   /* unused */     125
 # define DSA_F_DSA_NEW_METHOD                             103
 # define DSA_F_DSA_PARAM_DECODE                           119
 # define DSA_F_DSA_PRINT_FP                               105
@@ -317,12 +336,16 @@ void ERR_load_DSA_strings(void);
 # define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE                100
 # define DSA_R_DECODE_ERROR                               104
 # define DSA_R_INVALID_DIGEST_TYPE                        106
-# define DSA_R_INVALID_PARAMETERS                         112
+# define DSA_R_INVALID_PARAMETERS                         212
+# define DSA_R_KEY_SIZE_INVALID                           201
+# define DSA_R_KEY_SIZE_TOO_SMALL                         110
 # define DSA_R_MISSING_PARAMETERS                         101
 # define DSA_R_MODULUS_TOO_LARGE                          103
-# define DSA_R_NEED_NEW_SETUP_VALUES                      110
+# define DSA_R_NEED_NEW_SETUP_VALUES                      112
 # define DSA_R_NON_FIPS_DSA_METHOD                        111
+# define DSA_R_NON_FIPS_METHOD                            111
 # define DSA_R_NO_PARAMETERS_SET                          107
+# define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE /* unused */ 112
 # define DSA_R_PARAMETER_ENCODING_ERROR                   105
 # define DSA_R_Q_NOT_PRIME                                113
 
diff -up openssl-1.0.2i/crypto/dsa/dsa_key.c.fips openssl-1.0.2i/crypto/dsa/dsa_key.c
--- openssl-1.0.2i/crypto/dsa/dsa_key.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa_key.c	2016-09-22 13:35:57.010220836 +0200
@@ -66,6 +66,34 @@
 
 # ifdef OPENSSL_FIPS
 #  include <openssl/fips.h>
+#  include <openssl/evp.h>
+
+static int fips_check_dsa(DSA *dsa)
+{
+    EVP_PKEY *pk;
+    unsigned char tbs[] = "DSA Pairwise Check Data";
+    int ret = 0;
+
+    if ((pk = EVP_PKEY_new()) == NULL)
+        goto err;
+
+    EVP_PKEY_set1_DSA(pk, dsa);
+
+    if (fips_pkey_signature_test(pk, tbs, -1, NULL, 0, NULL, 0, NULL))
+        ret = 1;
+
+ err:
+    if (ret == 0) {
+        FIPSerr(FIPS_F_FIPS_CHECK_DSA, FIPS_R_PAIRWISE_TEST_FAILED);
+        fips_set_selftest_fail();
+    }
+
+    if (pk)
+        EVP_PKEY_free(pk);
+
+    return ret;
+}
+
 # endif
 
 static int dsa_builtin_keygen(DSA *dsa);
@@ -81,10 +109,6 @@ int DSA_generate_key(DSA *dsa)
 # endif
     if (dsa->meth->dsa_keygen)
         return dsa->meth->dsa_keygen(dsa);
-# ifdef OPENSSL_FIPS
-    if (FIPS_mode())
-        return FIPS_dsa_generate_key(dsa);
-# endif
     return dsa_builtin_keygen(dsa);
 }
 
@@ -94,6 +118,14 @@ static int dsa_builtin_keygen(DSA *dsa)
     BN_CTX *ctx = NULL;
     BIGNUM *pub_key = NULL, *priv_key = NULL;
 
+# ifdef OPENSSL_FIPS
+    if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
+        && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
+        DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL);
+        goto err;
+    }
+# endif
+
     if ((ctx = BN_CTX_new()) == NULL)
         goto err;
 
@@ -131,6 +163,13 @@ static int dsa_builtin_keygen(DSA *dsa)
 
     dsa->priv_key = priv_key;
     dsa->pub_key = pub_key;
+# ifdef OPENSSL_FIPS
+    if (FIPS_mode() && !fips_check_dsa(dsa)) {
+        dsa->pub_key = NULL;
+        dsa->priv_key = NULL;
+        goto err;
+    }
+# endif
     ok = 1;
 
  err:
diff -up openssl-1.0.2i/crypto/dsa/dsa_lib.c.fips openssl-1.0.2i/crypto/dsa/dsa_lib.c
--- openssl-1.0.2i/crypto/dsa/dsa_lib.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa_lib.c	2016-09-22 13:35:57.010220836 +0200
@@ -86,14 +86,7 @@ void DSA_set_default_method(const DSA_ME
 const DSA_METHOD *DSA_get_default_method(void)
 {
     if (!default_DSA_method) {
-#ifdef OPENSSL_FIPS
-        if (FIPS_mode())
-            return FIPS_dsa_openssl();
-        else
-            return DSA_OpenSSL();
-#else
         default_DSA_method = DSA_OpenSSL();
-#endif
     }
     return default_DSA_method;
 }
diff -up openssl-1.0.2i/crypto/dsa/dsa_locl.h.fips openssl-1.0.2i/crypto/dsa/dsa_locl.h
--- openssl-1.0.2i/crypto/dsa/dsa_locl.h.fips	2016-09-22 13:35:56.790215765 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa_locl.h	2016-09-22 13:35:57.010220836 +0200
@@ -56,7 +56,7 @@
 
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                          const EVP_MD *evpmd, const unsigned char *seed_in,
-                         size_t seed_len, unsigned char *seed_out,
+                         size_t seed_len,
                          int *counter_ret, unsigned long *h_ret,
                          BN_GENCB *cb);
 
diff -up openssl-1.0.2i/crypto/dsa/dsa_ossl.c.fips openssl-1.0.2i/crypto/dsa/dsa_ossl.c
--- openssl-1.0.2i/crypto/dsa/dsa_ossl.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa_ossl.c	2016-09-22 13:35:57.010220836 +0200
@@ -65,6 +65,9 @@
 #include <openssl/dsa.h>
 #include <openssl/rand.h>
 #include <openssl/asn1.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
 
 static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
 static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
@@ -83,7 +86,7 @@ static DSA_METHOD openssl_dsa_meth = {
     NULL,                       /* dsa_bn_mod_exp, */
     dsa_init,
     dsa_finish,
-    0,
+    DSA_FLAG_FIPS_METHOD,
     NULL,
     NULL,
     NULL
@@ -140,6 +143,19 @@ static DSA_SIG *dsa_do_sign(const unsign
     DSA_SIG *ret = NULL;
     int noredo = 0;
 
+#ifdef OPENSSL_FIPS
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_DSA_DO_SIGN, FIPS_R_FIPS_SELFTEST_FAILED);
+        return NULL;
+    }
+
+    if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
+        && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
+        DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL);
+        return NULL;
+    }
+#endif
+
     BN_init(&m);
     BN_init(&xr);
 
@@ -335,6 +351,18 @@ static int dsa_do_verify(const unsigned
         DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE);
         return -1;
     }
+#ifdef OPENSSL_FIPS
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_DSA_DO_VERIFY, FIPS_R_FIPS_SELFTEST_FAILED);
+        return -1;
+    }
+
+    if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
+        && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) {
+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL);
+        return -1;
+    }
+#endif
 
     if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
         DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE);
@@ -415,6 +443,9 @@ static int dsa_do_verify(const unsigned
 
 static int dsa_init(DSA *dsa)
 {
+#ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+#endif
     dsa->flags |= DSA_FLAG_CACHE_MONT_P;
     return (1);
 }
diff -up openssl-1.0.2i/crypto/dsa/dsa_pmeth.c.fips openssl-1.0.2i/crypto/dsa/dsa_pmeth.c
--- openssl-1.0.2i/crypto/dsa/dsa_pmeth.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dsa/dsa_pmeth.c	2016-09-22 13:35:57.010220836 +0200
@@ -253,7 +253,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CT
     if (!dsa)
         return 0;
     ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
-                               NULL, 0, NULL, NULL, NULL, pcb);
+                               NULL, 0, NULL, NULL, pcb);
     if (ret)
         EVP_PKEY_assign_DSA(pkey, dsa);
     else
diff -up openssl-1.0.2i/crypto/dsa/dsatest.c.fips openssl-1.0.2i/crypto/dsa/dsatest.c
--- openssl-1.0.2i/crypto/dsa/dsatest.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/dsa/dsatest.c	2016-09-22 13:35:57.010220836 +0200
@@ -100,36 +100,41 @@ static int MS_CALLBACK dsa_cb(int p, int
  * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1
  */
 static unsigned char seed[20] = {
-    0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b, 0x40,
-    0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
+    0x02, 0x47, 0x11, 0x92, 0x11, 0x88, 0xC8, 0xFB, 0xAF, 0x48, 0x4C, 0x62,
+    0xDF, 0xA5, 0xBE, 0xA0, 0xA4, 0x3C, 0x56, 0xE3,
 };
 
 static unsigned char out_p[] = {
-    0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa,
-    0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb,
-    0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7,
-    0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5,
-    0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf,
-    0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac,
-    0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2,
-    0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
+    0xAC, 0xCB, 0x1E, 0x63, 0x60, 0x69, 0x0C, 0xFB, 0x06, 0x19, 0x68, 0x3E,
+    0xA5, 0x01, 0x5A, 0xA2, 0x15, 0x5C, 0xE2, 0x99, 0x2D, 0xD5, 0x30, 0x99,
+    0x7E, 0x5F, 0x8D, 0xE2, 0xF7, 0xC6, 0x2E, 0x8D, 0xA3, 0x9F, 0x58, 0xAD,
+    0xD6, 0xA9, 0x7D, 0x0E, 0x0D, 0x95, 0x53, 0xA6, 0x71, 0x3A, 0xDE, 0xAB,
+    0xAC, 0xE9, 0xF4, 0x36, 0x55, 0x9E, 0xB9, 0xD6, 0x93, 0xBF, 0xF3, 0x18,
+    0x1C, 0x14, 0x7B, 0xA5, 0x42, 0x2E, 0xCD, 0x00, 0xEB, 0x35, 0x3B, 0x1B,
+    0xA8, 0x51, 0xBB, 0xE1, 0x58, 0x42, 0x85, 0x84, 0x22, 0xA7, 0x97, 0x5E,
+    0x99, 0x6F, 0x38, 0x20, 0xBD, 0x9D, 0xB6, 0xD9, 0x33, 0x37, 0x2A, 0xFD,
+    0xBB, 0xD4, 0xBC, 0x0C, 0x2A, 0x67, 0xCB, 0x9F, 0xBB, 0xDF, 0xF9, 0x93,
+    0xAA, 0xD6, 0xF0, 0xD6, 0x95, 0x0B, 0x5D, 0x65, 0x14, 0xD0, 0x18, 0x9D,
+    0xC6, 0xAF, 0xF0, 0xC6, 0x37, 0x7C, 0xF3, 0x5F,
 };
 
 static unsigned char out_q[] = {
-    0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee,
-    0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e,
-    0xda, 0xce, 0x91, 0x5f,
+    0xE3, 0x8E, 0x5E, 0x6D, 0xBF, 0x2B, 0x79, 0xF8, 0xC5, 0x4B, 0x89, 0x8B,
+    0xBA, 0x2D, 0x91, 0xC3, 0x6C, 0x80, 0xAC, 0x87,
 };
 
 static unsigned char out_g[] = {
-    0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13,
-    0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00,
-    0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb,
-    0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e,
-    0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf,
-    0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c,
-    0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c,
-    0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
+    0x42, 0x4A, 0x04, 0x4E, 0x79, 0xB4, 0x99, 0x7F, 0xFD, 0x58, 0x36, 0x2C,
+    0x1B, 0x5F, 0x18, 0x7E, 0x0D, 0xCC, 0xAB, 0x81, 0xC9, 0x5D, 0x10, 0xCE,
+    0x4E, 0x80, 0x7E, 0x58, 0xB4, 0x34, 0x3F, 0xA7, 0x45, 0xC7, 0xAA, 0x36,
+    0x24, 0x42, 0xA9, 0x3B, 0xE8, 0x0E, 0x04, 0x02, 0x2D, 0xFB, 0xA6, 0x13,
+    0xB9, 0xB5, 0x15, 0xA5, 0x56, 0x07, 0x35, 0xE4, 0x03, 0xB6, 0x79, 0x7C,
+    0x62, 0xDD, 0xDF, 0x3F, 0x71, 0x3A, 0x9D, 0x8B, 0xC4, 0xF6, 0xE7, 0x1D,
+    0x52, 0xA8, 0xA9, 0x43, 0x1D, 0x33, 0x51, 0x88, 0x39, 0xBD, 0x73, 0xE9,
+    0x5F, 0xBE, 0x82, 0x49, 0x27, 0xE6, 0xB5, 0x53, 0xC1, 0x38, 0xAC, 0x2F,
+    0x6D, 0x97, 0x6C, 0xEB, 0x67, 0xC1, 0x5F, 0x67, 0xF8, 0x35, 0x05, 0x5E,
+    0xD5, 0x68, 0x80, 0xAA, 0x96, 0xCA, 0x0B, 0x8A, 0xE6, 0xF1, 0xB1, 0x41,
+    0xC6, 0x75, 0x94, 0x0A, 0x0A, 0x2A, 0xFA, 0x29,
 };
 
 static const unsigned char str1[] = "12345678901234567890";
@@ -162,7 +167,7 @@ int main(int argc, char **argv)
     BIO_printf(bio_err, "test generation of DSA parameters\n");
 
     BN_GENCB_set(&cb, dsa_cb, bio_err);
-    if (((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512,
+    if (((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 1024,
                                                                    seed, 20,
                                                                    &counter,
                                                                    &h, &cb))
@@ -176,8 +181,8 @@ int main(int argc, char **argv)
     BIO_printf(bio_err, "\ncounter=%d h=%ld\n", counter, h);
 
     DSA_print(bio_err, dsa, 0);
-    if (counter != 105) {
-        BIO_printf(bio_err, "counter should be 105\n");
+    if (counter != 239) {
+        BIO_printf(bio_err, "counter should be 239\n");
         goto end;
     }
     if (h != 2) {
diff -up openssl-1.0.2i/crypto/engine/eng_all.c.fips openssl-1.0.2i/crypto/engine/eng_all.c
--- openssl-1.0.2i/crypto/engine/eng_all.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/engine/eng_all.c	2016-09-22 13:35:57.011220859 +0200
@@ -59,11 +59,25 @@
 
 #include "cryptlib.h"
 #include "eng_int.h"
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
 
 void ENGINE_load_builtin_engines(void)
 {
     /* Some ENGINEs need this */
     OPENSSL_cpuid_setup();
+#ifdef OPENSSL_FIPS
+    OPENSSL_init_library();
+    if (FIPS_mode()) {
+        /* We allow loading dynamic engine as a third party
+           engine might be FIPS validated.
+           User is disallowed to load non-validated engines
+           by security policy. */
+        ENGINE_load_dynamic();
+        return;
+    }
+#endif
 #if 0
     /*
      * There's no longer any need for an "openssl" ENGINE unless, one day, it
diff -up openssl-1.0.2i/crypto/evp/c_allc.c.fips openssl-1.0.2i/crypto/evp/c_allc.c
--- openssl-1.0.2i/crypto/evp/c_allc.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/c_allc.c	2016-09-22 13:35:57.011220859 +0200
@@ -65,6 +65,10 @@
 void OpenSSL_add_all_ciphers(void)
 {
 
+#ifdef OPENSSL_FIPS
+    OPENSSL_init_library();
+    if (!FIPS_mode()) {
+#endif
 #ifndef OPENSSL_NO_DES
     EVP_add_cipher(EVP_des_cfb());
     EVP_add_cipher(EVP_des_cfb1());
@@ -238,4 +242,64 @@ void OpenSSL_add_all_ciphers(void)
     EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
     EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
 #endif
+#ifdef OPENSSL_FIPS
+    } else {
+# ifndef OPENSSL_NO_DES
+        EVP_add_cipher(EVP_des_ede_cfb());
+        EVP_add_cipher(EVP_des_ede3_cfb());
+
+        EVP_add_cipher(EVP_des_ede_ofb());
+        EVP_add_cipher(EVP_des_ede3_ofb());
+
+        EVP_add_cipher(EVP_des_ede_cbc());
+        EVP_add_cipher(EVP_des_ede3_cbc());
+        EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
+        EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
+
+        EVP_add_cipher(EVP_des_ede());
+        EVP_add_cipher(EVP_des_ede3());
+# endif
+
+# ifndef OPENSSL_NO_AES
+        EVP_add_cipher(EVP_aes_128_ecb());
+        EVP_add_cipher(EVP_aes_128_cbc());
+        EVP_add_cipher(EVP_aes_128_cfb());
+        EVP_add_cipher(EVP_aes_128_cfb1());
+        EVP_add_cipher(EVP_aes_128_cfb8());
+        EVP_add_cipher(EVP_aes_128_ofb());
+        EVP_add_cipher(EVP_aes_128_ctr());
+        EVP_add_cipher(EVP_aes_128_gcm());
+        EVP_add_cipher(EVP_aes_128_xts());
+        EVP_add_cipher(EVP_aes_128_ccm());
+        EVP_add_cipher(EVP_aes_128_wrap());
+        EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
+        EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
+        EVP_add_cipher(EVP_aes_192_ecb());
+        EVP_add_cipher(EVP_aes_192_cbc());
+        EVP_add_cipher(EVP_aes_192_cfb());
+        EVP_add_cipher(EVP_aes_192_cfb1());
+        EVP_add_cipher(EVP_aes_192_cfb8());
+        EVP_add_cipher(EVP_aes_192_ofb());
+        EVP_add_cipher(EVP_aes_192_ctr());
+        EVP_add_cipher(EVP_aes_192_gcm());
+        EVP_add_cipher(EVP_aes_192_ccm());
+        EVP_add_cipher(EVP_aes_192_wrap());
+        EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
+        EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
+        EVP_add_cipher(EVP_aes_256_ecb());
+        EVP_add_cipher(EVP_aes_256_cbc());
+        EVP_add_cipher(EVP_aes_256_cfb());
+        EVP_add_cipher(EVP_aes_256_cfb1());
+        EVP_add_cipher(EVP_aes_256_cfb8());
+        EVP_add_cipher(EVP_aes_256_ofb());
+        EVP_add_cipher(EVP_aes_256_ctr());
+        EVP_add_cipher(EVP_aes_256_gcm());
+        EVP_add_cipher(EVP_aes_256_xts());
+        EVP_add_cipher(EVP_aes_256_ccm());
+        EVP_add_cipher(EVP_aes_256_wrap());
+        EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
+        EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
+# endif
+    }
+#endif
 }
diff -up openssl-1.0.2i/crypto/evp/c_alld.c.fips openssl-1.0.2i/crypto/evp/c_alld.c
--- openssl-1.0.2i/crypto/evp/c_alld.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/c_alld.c	2016-09-22 13:35:57.011220859 +0200
@@ -64,51 +64,81 @@
 
 void OpenSSL_add_all_digests(void)
 {
+#ifdef OPENSSL_FIPS
+    OPENSSL_init_library();
+    if (!FIPS_mode()) {
+#endif
 #ifndef OPENSSL_NO_MD4
-    EVP_add_digest(EVP_md4());
+        EVP_add_digest(EVP_md4());
 #endif
 #ifndef OPENSSL_NO_MD5
-    EVP_add_digest(EVP_md5());
-    EVP_add_digest_alias(SN_md5, "ssl2-md5");
-    EVP_add_digest_alias(SN_md5, "ssl3-md5");
+        EVP_add_digest(EVP_md5());
+        EVP_add_digest_alias(SN_md5, "ssl2-md5");
+        EVP_add_digest_alias(SN_md5, "ssl3-md5");
 #endif
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
-    EVP_add_digest(EVP_sha());
+        EVP_add_digest(EVP_sha());
 # ifndef OPENSSL_NO_DSA
-    EVP_add_digest(EVP_dss());
+        EVP_add_digest(EVP_dss());
 # endif
 #endif
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
-    EVP_add_digest(EVP_sha1());
-    EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
-    EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
+        EVP_add_digest(EVP_sha1());
+        EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
+        EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
 # ifndef OPENSSL_NO_DSA
-    EVP_add_digest(EVP_dss1());
-    EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
-    EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
-    EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
+        EVP_add_digest(EVP_dss1());
+        EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
+        EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
+        EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
 # endif
 # ifndef OPENSSL_NO_ECDSA
-    EVP_add_digest(EVP_ecdsa());
+        EVP_add_digest(EVP_ecdsa());
 # endif
 #endif
 #if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
-    EVP_add_digest(EVP_mdc2());
+        EVP_add_digest(EVP_mdc2());
 #endif
 #ifndef OPENSSL_NO_RIPEMD
-    EVP_add_digest(EVP_ripemd160());
-    EVP_add_digest_alias(SN_ripemd160, "ripemd");
-    EVP_add_digest_alias(SN_ripemd160, "rmd160");
+        EVP_add_digest(EVP_ripemd160());
+        EVP_add_digest_alias(SN_ripemd160, "ripemd");
+        EVP_add_digest_alias(SN_ripemd160, "rmd160");
 #endif
 #ifndef OPENSSL_NO_SHA256
-    EVP_add_digest(EVP_sha224());
-    EVP_add_digest(EVP_sha256());
+        EVP_add_digest(EVP_sha224());
+        EVP_add_digest(EVP_sha256());
 #endif
 #ifndef OPENSSL_NO_SHA512
-    EVP_add_digest(EVP_sha384());
-    EVP_add_digest(EVP_sha512());
+        EVP_add_digest(EVP_sha384());
+        EVP_add_digest(EVP_sha512());
 #endif
 #ifndef OPENSSL_NO_WHIRLPOOL
-    EVP_add_digest(EVP_whirlpool());
+        EVP_add_digest(EVP_whirlpool());
+#endif
+#ifdef OPENSSL_FIPS
+    } else {
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+        EVP_add_digest(EVP_sha1());
+        EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
+        EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
+#  ifndef OPENSSL_NO_DSA
+        EVP_add_digest(EVP_dss1());
+        EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
+        EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
+        EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
+#  endif
+#  ifndef OPENSSL_NO_ECDSA
+        EVP_add_digest(EVP_ecdsa());
+#  endif
+# endif
+# ifndef OPENSSL_NO_SHA256
+        EVP_add_digest(EVP_sha224());
+        EVP_add_digest(EVP_sha256());
+# endif
+# ifndef OPENSSL_NO_SHA512
+        EVP_add_digest(EVP_sha384());
+        EVP_add_digest(EVP_sha512());
+# endif
+    }
 #endif
 }
diff -up openssl-1.0.2i/crypto/evp/digest.c.fips openssl-1.0.2i/crypto/evp/digest.c
--- openssl-1.0.2i/crypto/evp/digest.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/digest.c	2016-09-22 13:45:40.054658929 +0200
@@ -143,18 +143,55 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, cons
     return EVP_DigestInit_ex(ctx, type, NULL);
 }
 
+#ifdef OPENSSL_FIPS
+
+/* The purpose of these is to trap programs that attempt to use non FIPS
+ * algorithms in FIPS mode and ignore the errors.
+ */
+
+static int bad_init(EVP_MD_CTX *ctx)
+{
+    FIPS_ERROR_IGNORED("Digest init");
+    return 0;
+}
+
+static int bad_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    FIPS_ERROR_IGNORED("Digest update");
+    return 0;
+}
+
+static int bad_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    FIPS_ERROR_IGNORED("Digest Final");
+    return 0;
+}
+
+static const EVP_MD bad_md = {
+    0,
+    0,
+    0,
+    0,
+    bad_init,
+    bad_update,
+    bad_final,
+    NULL,
+    NULL,
+    NULL,
+    0,
+    {0, 0, 0, 0},
+};
+
+#endif
+
 int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
 {
     EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
 #ifdef OPENSSL_FIPS
-    /* If FIPS mode switch to approved implementation if possible */
-    if (FIPS_mode()) {
-        const EVP_MD *fipsmd;
-        if (type) {
-            fipsmd = evp_get_fips_md(type);
-            if (fipsmd)
-                type = fipsmd;
-        }
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_EVP_DIGESTINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED);
+        ctx->digest = &bad_md;
+        return 0;
     }
 #endif
 #ifndef OPENSSL_NO_ENGINE
@@ -212,6 +249,16 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c
     }
 #endif
     if (ctx->digest != type) {
+#ifdef OPENSSL_FIPS
+        if (FIPS_mode()) {
+            if (!(type->flags & EVP_MD_FLAG_FIPS)
+                && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) {
+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS);
+                ctx->digest = &bad_md;
+                return 0;
+            }
+        }
+#endif
         if (ctx->digest && ctx->digest->ctx_size) {
             OPENSSL_free(ctx->md_data);
             ctx->md_data = NULL;
@@ -238,23 +285,13 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c
     }
     if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
         return 1;
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode()) {
-        if (FIPS_digestinit(ctx, type))
-            return 1;
-        OPENSSL_free(ctx->md_data);
-        ctx->md_data = NULL;
-        return 0;
-    }
-#endif
     return ctx->digest->init(ctx);
 }
 
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
 #ifdef OPENSSL_FIPS
-    if (FIPS_mode())
-        return FIPS_digestupdate(ctx, data, count);
+    FIPS_selftest_check();
 #endif
     return ctx->update(ctx, data, count);
 }
@@ -272,11 +309,10 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, uns
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 {
     int ret;
+
 #ifdef OPENSSL_FIPS
-    if (FIPS_mode())
-        return FIPS_digestfinal(ctx, md, size);
+    FIPS_selftest_check();
 #endif
-
     OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
     ret = ctx->digest->final(ctx, md);
     if (size != NULL)
@@ -375,7 +411,6 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
 /* This call frees resources associated with the context */
 int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
 {
-#ifndef OPENSSL_FIPS
     /*
      * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
      * sometimes only copies of the context are ever finalised.
@@ -388,7 +423,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
         OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
         OPENSSL_free(ctx->md_data);
     }
-#endif
     if (ctx->pctx)
         EVP_PKEY_CTX_free(ctx->pctx);
 #ifndef OPENSSL_NO_ENGINE
@@ -399,9 +433,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
          */
         ENGINE_finish(ctx->engine);
 #endif
-#ifdef OPENSSL_FIPS
-    FIPS_md_ctx_cleanup(ctx);
-#endif
     memset(ctx, '\0', sizeof *ctx);
 
     return 1;
diff -up openssl-1.0.2i/crypto/evp/e_aes.c.fips openssl-1.0.2i/crypto/evp/e_aes.c
--- openssl-1.0.2i/crypto/evp/e_aes.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/e_aes.c	2016-09-22 13:35:57.011220859 +0200
@@ -60,9 +60,6 @@
 # include "modes_lcl.h"
 # include <openssl/rand.h>
 
-# undef EVP_CIPH_FLAG_FIPS
-# define EVP_CIPH_FLAG_FIPS 0
-
 typedef struct {
     union {
         double align;
@@ -1159,6 +1156,11 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *
     case EVP_CTRL_GCM_SET_IVLEN:
         if (arg <= 0)
             return 0;
+# ifdef OPENSSL_FIPS
+        if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)
+            && arg < 12)
+            return 0;
+# endif
         /* Allocate memory for IV if needed */
         if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
             if (gctx->iv != c->iv)
@@ -1727,6 +1729,14 @@ static int aes_xts_cipher(EVP_CIPHER_CTX
         return 0;
     if (!out || !in || len < AES_BLOCK_SIZE)
         return 0;
+# ifdef OPENSSL_FIPS
+    /* Requirement of SP800-38E */
+    if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) &&
+        (len > (1UL << 20) * 16)) {
+        EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE);
+        return 0;
+    }
+# endif
     if (xctx->stream)
         (*xctx->stream) (in, out, len,
                          xctx->xts.key1, xctx->xts.key2, ctx->iv);
diff -up openssl-1.0.2i/crypto/evp/e_des3.c.fips openssl-1.0.2i/crypto/evp/e_des3.c
--- openssl-1.0.2i/crypto/evp/e_des3.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/e_des3.c	2016-09-22 13:35:57.012220882 +0200
@@ -65,10 +65,6 @@
 # include <openssl/des.h>
 # include <openssl/rand.h>
 
-/* Block use of implementations in FIPS mode */
-# undef EVP_CIPH_FLAG_FIPS
-# define EVP_CIPH_FLAG_FIPS      0
-
 typedef struct {
     union {
         double align;
diff -up openssl-1.0.2i/crypto/evp/e_null.c.fips openssl-1.0.2i/crypto/evp/e_null.c
--- openssl-1.0.2i/crypto/evp/e_null.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/e_null.c	2016-09-22 13:35:57.012220882 +0200
@@ -68,7 +68,7 @@ static int null_cipher(EVP_CIPHER_CTX *c
 static const EVP_CIPHER n_cipher = {
     NID_undef,
     1, 0, 0,
-    0,
+    EVP_CIPH_FLAG_FIPS,
     null_init_key,
     null_cipher,
     NULL,
diff -up openssl-1.0.2i/crypto/evp/evp_enc.c.fips openssl-1.0.2i/crypto/evp/evp_enc.c
--- openssl-1.0.2i/crypto/evp/evp_enc.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/evp_enc.c	2016-09-22 13:46:12.998418222 +0200
@@ -69,16 +69,73 @@
 #endif
 #include "evp_locl.h"
 
-#ifdef OPENSSL_FIPS
-# define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl)
-#else
-# define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
-#endif
+#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl)
 
 const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT;
 
+#ifdef OPENSSL_FIPS
+
+/* The purpose of these is to trap programs that attempt to use non FIPS
+ * algorithms in FIPS mode and ignore the errors.
+ */
+
+static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                    const unsigned char *iv, int enc)
+{
+    FIPS_ERROR_IGNORED("Cipher init");
+    return 0;
+}
+
+static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                         const unsigned char *in, unsigned int inl)
+{
+    FIPS_ERROR_IGNORED("Cipher update");
+    return 0;
+}
+
+/* NB: no cleanup because it is allowed after failed init */
+
+static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
+{
+    FIPS_ERROR_IGNORED("Cipher set_asn1");
+    return 0;
+}
+
+static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
+{
+    FIPS_ERROR_IGNORED("Cipher get_asn1");
+    return 0;
+}
+
+static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+    FIPS_ERROR_IGNORED("Cipher ctrl");
+    return 0;
+}
+
+static const EVP_CIPHER bad_cipher = {
+    0,
+    0,
+    0,
+    0,
+    0,
+    bad_init,
+    bad_do_cipher,
+    NULL,
+    0,
+    bad_set_asn1,
+    bad_get_asn1,
+    bad_ctrl,
+    NULL
+};
+
+#endif
+
 void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
 {
+#ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+#endif
     memset(ctx, 0, sizeof(EVP_CIPHER_CTX));
     /* ctx->cipher=NULL; */
 }
@@ -110,6 +167,13 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
             enc = 1;
         ctx->encrypt = enc;
     }
+#ifdef OPENSSL_FIPS
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_EVP_CIPHERINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED);
+        ctx->cipher = &bad_cipher;
+        return 0;
+    }
+#endif
 #ifndef OPENSSL_NO_ENGINE
     /*
      * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
@@ -168,16 +232,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
             ctx->engine = NULL;
 #endif
 
-#ifdef OPENSSL_FIPS
-        if (FIPS_mode()) {
-            const EVP_CIPHER *fcipher = NULL;
-            if (cipher)
-                fcipher = evp_get_fips_cipher(cipher);
-            if (fcipher)
-                cipher = fcipher;
-            return FIPS_cipherinit(ctx, cipher, key, iv, enc);
-        }
-#endif
         ctx->cipher = cipher;
         if (ctx->cipher->ctx_size) {
             ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
@@ -204,10 +258,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
 #ifndef OPENSSL_NO_ENGINE
  skip_to_init:
 #endif
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode())
-        return FIPS_cipherinit(ctx, cipher, key, iv, enc);
-#endif
     /* we assume block size is a power of 2 in *cryptUpdate */
     OPENSSL_assert(ctx->cipher->block_size == 1
                    || ctx->cipher->block_size == 8
@@ -253,6 +303,19 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct
             break;
         }
     }
+#ifdef OPENSSL_FIPS
+    /* After 'key' is set no further parameters changes are permissible.
+     * So only check for non FIPS enabling at this point.
+     */
+    if (key && FIPS_mode()) {
+        if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS)
+            & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) {
+            EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS);
+            ctx->cipher = &bad_cipher;
+            return 0;
+        }
+    }
+#endif
 
     if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
         if (!ctx->cipher->init(ctx, key, iv, enc))
@@ -554,7 +617,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX
 
 int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
 {
-#ifndef OPENSSL_FIPS
     if (c->cipher != NULL) {
         if (c->cipher->cleanup && !c->cipher->cleanup(c))
             return 0;
@@ -564,7 +626,6 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CT
     }
     if (c->cipher_data)
         OPENSSL_free(c->cipher_data);
-#endif
 #ifndef OPENSSL_NO_ENGINE
     if (c->engine)
         /*
@@ -573,9 +634,6 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CT
          */
         ENGINE_finish(c->engine);
 #endif
-#ifdef OPENSSL_FIPS
-    FIPS_cipher_ctx_cleanup(c);
-#endif
     memset(c, 0, sizeof(EVP_CIPHER_CTX));
     return 1;
 }
diff -up openssl-1.0.2i/crypto/evp/evp.h.fips openssl-1.0.2i/crypto/evp/evp.h
--- openssl-1.0.2i/crypto/evp/evp.h.fips	2016-09-22 13:35:56.902218346 +0200
+++ openssl-1.0.2i/crypto/evp/evp.h	2016-09-22 13:35:57.012220882 +0200
@@ -122,6 +122,10 @@
 extern "C" {
 #endif
 
+# ifdef OPENSSL_FIPS
+#  include <openssl/fips.h>
+# endif
+
 /*
  * Type needs to be a bit field Sub-type needs to be for variations on the
  * method, as in, can it do arbitrary encryption....
@@ -285,11 +289,6 @@ struct env_md_ctx_st {
                                                 * cleaned */
 # define EVP_MD_CTX_FLAG_REUSE           0x0004/* Don't free up ctx->md_data
                                                 * in EVP_MD_CTX_cleanup */
-/*
- * FIPS and pad options are ignored in 1.0.0, definitions are here so we
- * don't accidentally reuse the values for other purposes.
- */
-
 # define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW  0x0008/* Allow use of non FIPS
                                                 * digest in FIPS mode */
 
@@ -302,6 +301,10 @@ struct env_md_ctx_st {
 # define EVP_MD_CTX_FLAG_PAD_PKCS1       0x00/* PKCS#1 v1.5 mode */
 # define EVP_MD_CTX_FLAG_PAD_X931        0x10/* X9.31 mode */
 # define EVP_MD_CTX_FLAG_PAD_PSS         0x20/* PSS mode */
+# define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \
+                ((ctx->flags>>16) &0xFFFF) /* seed length */
+# define EVP_MD_CTX_FLAG_PSS_MDLEN       0xFFFF/* salt len same as digest */
+# define EVP_MD_CTX_FLAG_PSS_MREC        0xFFFE/* salt max or auto recovered */
 
 # define EVP_MD_CTX_FLAG_NO_INIT         0x0100/* Don't initialize md_data */
 
@@ -363,15 +366,15 @@ struct evp_cipher_st {
 /* cipher handles random key generation */
 # define         EVP_CIPH_RAND_KEY               0x200
 /* cipher has its own additional copying logic */
-# define         EVP_CIPH_CUSTOM_COPY            0x400
+# define         EVP_CIPH_CUSTOM_COPY            0x4000
 /* Allow use default ASN1 get/set iv */
 # define         EVP_CIPH_FLAG_DEFAULT_ASN1      0x1000
 /* Buffer length in bits not bytes: CFB1 mode only */
 # define         EVP_CIPH_FLAG_LENGTH_BITS       0x2000
 /* Note if suitable for use in FIPS mode */
-# define         EVP_CIPH_FLAG_FIPS              0x4000
+# define         EVP_CIPH_FLAG_FIPS              0x400
 /* Allow non FIPS cipher in FIPS mode */
-# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x8000
+# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x800
 /*
  * Cipher handles any and all padding logic as well as finalisation.
  */
diff -up openssl-1.0.2i/crypto/evp/evp_lib.c.fips openssl-1.0.2i/crypto/evp/evp_lib.c
--- openssl-1.0.2i/crypto/evp/evp_lib.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/evp_lib.c	2016-09-22 13:35:57.012220882 +0200
@@ -60,10 +60,6 @@
 #include "cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#ifdef OPENSSL_FIPS
-# include <openssl/fips.h>
-# include "evp_locl.h"
-#endif
 
 int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
 {
@@ -224,6 +220,9 @@ int EVP_CIPHER_CTX_block_size(const EVP_
 int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                const unsigned char *in, unsigned int inl)
 {
+#ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+#endif
     return ctx->cipher->do_cipher(ctx, out, in, inl);
 }
 
@@ -234,22 +233,12 @@ const EVP_CIPHER *EVP_CIPHER_CTX_cipher(
 
 unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
 {
-#ifdef OPENSSL_FIPS
-    const EVP_CIPHER *fcipher;
-    fcipher = evp_get_fips_cipher(cipher);
-    if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS)
-        return cipher->flags | EVP_CIPH_FLAG_FIPS;
-#endif
     return cipher->flags;
 }
 
 unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
 {
-#ifdef OPENSSL_FIPS
-    return EVP_CIPHER_flags(ctx->cipher);
-#else
     return ctx->cipher->flags;
-#endif
 }
 
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
@@ -316,40 +305,8 @@ int EVP_MD_size(const EVP_MD *md)
     return md->md_size;
 }
 
-#ifdef OPENSSL_FIPS
-
-const EVP_MD *evp_get_fips_md(const EVP_MD *md)
-{
-    int nid = EVP_MD_type(md);
-    if (nid == NID_dsa)
-        return FIPS_evp_dss1();
-    else if (nid == NID_dsaWithSHA)
-        return FIPS_evp_dss();
-    else if (nid == NID_ecdsa_with_SHA1)
-        return FIPS_evp_ecdsa();
-    else
-        return FIPS_get_digestbynid(nid);
-}
-
-const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher)
-{
-    int nid = cipher->nid;
-    if (nid == NID_undef)
-        return FIPS_evp_enc_null();
-    else
-        return FIPS_get_cipherbynid(nid);
-}
-
-#endif
-
 unsigned long EVP_MD_flags(const EVP_MD *md)
 {
-#ifdef OPENSSL_FIPS
-    const EVP_MD *fmd;
-    fmd = evp_get_fips_md(md);
-    if (fmd && fmd->flags & EVP_MD_FLAG_FIPS)
-        return md->flags | EVP_MD_FLAG_FIPS;
-#endif
     return md->flags;
 }
 
diff -up openssl-1.0.2i/crypto/evp/evp_locl.h.fips openssl-1.0.2i/crypto/evp/evp_locl.h
--- openssl-1.0.2i/crypto/evp/evp_locl.h.fips	2016-09-22 13:35:56.898218254 +0200
+++ openssl-1.0.2i/crypto/evp/evp_locl.h	2016-09-22 13:35:57.013220905 +0200
@@ -258,10 +258,8 @@ const EVP_CIPHER *EVP_##cname##_ecb(void
         BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
         BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
                              NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
-                             0, cipher##_init_key, NULL, \
-                             EVP_CIPHER_set_asn1_iv, \
-                             EVP_CIPHER_get_asn1_iv, \
-                             NULL)
+                             EVP_CIPH_FLAG_DEFAULT_ASN1, \
+                             cipher##_init_key, NULL, NULL, NULL, NULL)
 
 struct evp_pkey_ctx_st {
     /* Method associated with this operation */
@@ -355,11 +353,6 @@ const EVP_CIPHER *evp_get_fips_cipher(co
 # define MD2_Init        private_MD2_Init
 # define MDC2_Init       private_MDC2_Init
 # define SHA_Init        private_SHA_Init
-# define SHA1_Init       private_SHA1_Init
-# define SHA224_Init     private_SHA224_Init
-# define SHA256_Init     private_SHA256_Init
-# define SHA384_Init     private_SHA384_Init
-# define SHA512_Init     private_SHA512_Init
 
 # define BF_set_key      private_BF_set_key
 # define CAST_set_key    private_CAST_set_key
@@ -367,7 +360,6 @@ const EVP_CIPHER *evp_get_fips_cipher(co
 # define SEED_set_key    private_SEED_set_key
 # define RC2_set_key     private_RC2_set_key
 # define RC4_set_key     private_RC4_set_key
-# define DES_set_key_unchecked   private_DES_set_key_unchecked
 # define Camellia_set_key        private_Camellia_set_key
 
 #endif
diff -up openssl-1.0.2i/crypto/evp/m_dss.c.fips openssl-1.0.2i/crypto/evp/m_dss.c
--- openssl-1.0.2i/crypto/evp/m_dss.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/m_dss.c	2016-09-22 13:35:57.013220905 +0200
@@ -86,7 +86,7 @@ static const EVP_MD dsa_md = {
     NID_dsaWithSHA,
     NID_dsaWithSHA,
     SHA_DIGEST_LENGTH,
-    EVP_MD_FLAG_PKEY_DIGEST,
+    EVP_MD_FLAG_PKEY_DIGEST | EVP_MD_FLAG_FIPS,
     init,
     update,
     final,
diff -up openssl-1.0.2i/crypto/evp/m_dss1.c.fips openssl-1.0.2i/crypto/evp/m_dss1.c
--- openssl-1.0.2i/crypto/evp/m_dss1.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/m_dss1.c	2016-09-22 13:35:57.013220905 +0200
@@ -87,7 +87,7 @@ static const EVP_MD dss1_md = {
     NID_dsa,
     NID_dsaWithSHA1,
     SHA_DIGEST_LENGTH,
-    EVP_MD_FLAG_PKEY_DIGEST,
+    EVP_MD_FLAG_PKEY_DIGEST | EVP_MD_FLAG_FIPS,
     init,
     update,
     final,
diff -up openssl-1.0.2i/crypto/evp/m_md2.c.fips openssl-1.0.2i/crypto/evp/m_md2.c
--- openssl-1.0.2i/crypto/evp/m_md2.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/m_md2.c	2016-09-22 13:35:57.013220905 +0200
@@ -68,6 +68,7 @@
 # ifndef OPENSSL_NO_RSA
 #  include <openssl/rsa.h>
 # endif
+# include "evp_locl.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
diff -up openssl-1.0.2i/crypto/evp/m_sha1.c.fips openssl-1.0.2i/crypto/evp/m_sha1.c
--- openssl-1.0.2i/crypto/evp/m_sha1.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/m_sha1.c	2016-09-22 13:35:57.013220905 +0200
@@ -87,7 +87,8 @@ static const EVP_MD sha1_md = {
     NID_sha1,
     NID_sha1WithRSAEncryption,
     SHA_DIGEST_LENGTH,
-    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT |
+        EVP_MD_FLAG_FIPS,
     init,
     update,
     final,
@@ -134,7 +135,8 @@ static const EVP_MD sha224_md = {
     NID_sha224,
     NID_sha224WithRSAEncryption,
     SHA224_DIGEST_LENGTH,
-    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT |
+        EVP_MD_FLAG_FIPS,
     init224,
     update256,
     final256,
@@ -154,7 +156,8 @@ static const EVP_MD sha256_md = {
     NID_sha256,
     NID_sha256WithRSAEncryption,
     SHA256_DIGEST_LENGTH,
-    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT |
+        EVP_MD_FLAG_FIPS,
     init256,
     update256,
     final256,
@@ -197,7 +200,8 @@ static const EVP_MD sha384_md = {
     NID_sha384,
     NID_sha384WithRSAEncryption,
     SHA384_DIGEST_LENGTH,
-    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT |
+        EVP_MD_FLAG_FIPS,
     init384,
     update512,
     final512,
@@ -217,7 +221,8 @@ static const EVP_MD sha512_md = {
     NID_sha512,
     NID_sha512WithRSAEncryption,
     SHA512_DIGEST_LENGTH,
-    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT,
+    EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT |
+        EVP_MD_FLAG_FIPS,
     init512,
     update512,
     final512,
diff -up openssl-1.0.2i/crypto/evp/p_sign.c.fips openssl-1.0.2i/crypto/evp/p_sign.c
--- openssl-1.0.2i/crypto/evp/p_sign.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/p_sign.c	2016-09-22 13:35:57.013220905 +0200
@@ -61,6 +61,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include <openssl/rsa.h>
 
 #ifdef undef
 void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
@@ -101,6 +102,22 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsig
             goto err;
         if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
             goto err;
+        if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931)
+            if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0)
+                goto err;
+        if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) {
+            int saltlen;
+            if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <=
+                0)
+                goto err;
+            saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx);
+            if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
+                saltlen = -1;
+            else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
+                saltlen = -2;
+            if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
+                goto err;
+        }
         if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
             goto err;
         *siglen = sltmp;
diff -up openssl-1.0.2i/crypto/evp/p_verify.c.fips openssl-1.0.2i/crypto/evp/p_verify.c
--- openssl-1.0.2i/crypto/evp/p_verify.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/evp/p_verify.c	2016-09-22 13:35:57.013220905 +0200
@@ -61,6 +61,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include <openssl/rsa.h>
 
 int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
                     unsigned int siglen, EVP_PKEY *pkey)
@@ -87,6 +88,22 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, con
             goto err;
         if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0)
             goto err;
+        if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931)
+            if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0)
+                goto err;
+        if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) {
+            int saltlen;
+            if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <=
+                0)
+                goto err;
+            saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx);
+            if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
+                saltlen = -1;
+            else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
+                saltlen = -2;
+            if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
+                goto err;
+        }
         i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
  err:
         EVP_PKEY_CTX_free(pkctx);
diff -up openssl-1.0.2i/crypto/fips/fips_aes_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_aes_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_aes_selftest.c.fips	2016-09-22 13:35:57.013220905 +0200
+++ openssl-1.0.2i/crypto/fips/fips_aes_selftest.c	2016-09-22 13:35:57.013220905 +0200
@@ -0,0 +1,365 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include <openssl/evp.h>
+
+#ifdef OPENSSL_FIPS
+static const struct {
+    const unsigned char key[16];
+    const unsigned char plaintext[16];
+    const unsigned char ciphertext[16];
+} tests[] = {
+    {
+        {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, {
+0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
+                0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A},},};
+
+static int corrupt_aes;
+
+void FIPS_corrupt_aes()
+{
+    corrupt_aes = 1;
+}
+
+int FIPS_selftest_aes()
+{
+    int n;
+    int ret = 0;
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+
+    for (n = 0; n < 1; ++n) {
+        unsigned char key[16];
+
+        memcpy(key, tests[n].key, sizeof(key));
+        if (corrupt_aes)
+            key[0]++;
+        if (fips_cipher_test(&ctx, EVP_aes_128_ecb(),
+                             key, NULL,
+                             tests[n].plaintext,
+                             tests[n].ciphertext, 16) <= 0)
+            goto err;
+    }
+    ret = 1;
+ err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    if (ret == 0)
+        FIPSerr(FIPS_F_FIPS_SELFTEST_AES, FIPS_R_SELFTEST_FAILED);
+    return ret;
+}
+
+/* AES-CCM test data from NIST public test vectors */
+
+static const unsigned char ccm_key[] = {
+    0xce, 0xb0, 0x09, 0xae, 0xa4, 0x45, 0x44, 0x51, 0xfe, 0xad, 0xf0, 0xe6,
+    0xb3, 0x6f, 0x45, 0x55, 0x5d, 0xd0, 0x47, 0x23, 0xba, 0xa4, 0x48, 0xe8
+};
+
+static const unsigned char ccm_nonce[] = {
+    0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7
+};
+
+static const unsigned char ccm_adata[] = {
+    0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, 0xc9, 0xab, 0x25, 0xc7,
+    0x5f, 0x10, 0xbd, 0xe7, 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5,
+    0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4
+};
+
+static const unsigned char ccm_pt[] = {
+    0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, 0xe6, 0x9c, 0x2a, 0x1f,
+    0x58, 0x93, 0x9d, 0xfe, 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10
+};
+
+static const unsigned char ccm_ct[] = {
+    0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, 0x87, 0xfd, 0x95, 0xa2,
+    0x8a, 0xd3, 0x92, 0xc8, 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd
+};
+
+static const unsigned char ccm_tag[] = {
+    0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, 0x23, 0xdc, 0x07, 0x44,
+    0x14, 0xdb, 0x50, 0x6d
+};
+
+int FIPS_selftest_aes_ccm(void)
+{
+    int ret = 0;
+    unsigned char out[128], tag[16];
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+    memset(out, 0, sizeof(out));
+    if (!EVP_CipherInit_ex(&ctx, EVP_aes_192_ccm(), NULL, NULL, NULL, 1))
+        goto err;
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN,
+                             sizeof(ccm_nonce), NULL))
+        goto err;
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG,
+                             sizeof(ccm_tag), NULL))
+        goto err;
+    if (!EVP_CipherInit_ex(&ctx, NULL, NULL, ccm_key, ccm_nonce, 1))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, NULL, sizeof(ccm_pt)) != sizeof(ccm_pt))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0)
+        goto err;
+    if (EVP_Cipher(&ctx, out, ccm_pt, sizeof(ccm_pt)) != sizeof(ccm_ct))
+        goto err;
+
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, 16, tag))
+        goto err;
+    if (memcmp(tag, ccm_tag, sizeof(ccm_tag))
+        || memcmp(out, ccm_ct, sizeof(ccm_ct)))
+        goto err;
+
+    memset(out, 0, sizeof(out));
+
+    if (!EVP_CipherInit_ex(&ctx, EVP_aes_192_ccm(), NULL, NULL, NULL, 0))
+        goto err;
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN,
+                             sizeof(ccm_nonce), NULL))
+        goto err;
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, 16, tag))
+        goto err;
+    if (!EVP_CipherInit_ex(&ctx, NULL, NULL, ccm_key, ccm_nonce, 0))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, NULL, sizeof(ccm_ct)) != sizeof(ccm_ct))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0)
+        goto err;
+    if (EVP_Cipher(&ctx, out, ccm_ct, sizeof(ccm_ct)) != sizeof(ccm_pt))
+        goto err;
+
+    if (memcmp(out, ccm_pt, sizeof(ccm_pt)))
+        goto err;
+
+    ret = 1;
+
+ err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+
+    if (ret == 0) {
+        FIPSerr(FIPS_F_FIPS_SELFTEST_AES_CCM, FIPS_R_SELFTEST_FAILED);
+        return 0;
+    } else
+        return ret;
+
+}
+
+/* AES-GCM test data from NIST public test vectors */
+
+static const unsigned char gcm_key[] = {
+    0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66,
+    0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69,
+    0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f
+};
+
+static const unsigned char gcm_iv[] = {
+    0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84
+};
+
+static const unsigned char gcm_pt[] = {
+    0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea,
+    0xcc, 0x2b, 0xf2, 0xa5
+};
+
+static const unsigned char gcm_aad[] = {
+    0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43,
+    0x7f, 0xec, 0x78, 0xde
+};
+
+static const unsigned char gcm_ct[] = {
+    0xf7, 0x26, 0x44, 0x13, 0xa8, 0x4c, 0x0e, 0x7c, 0xd5, 0x36, 0x86, 0x7e,
+    0xb9, 0xf2, 0x17, 0x36
+};
+
+static const unsigned char gcm_tag[] = {
+    0x67, 0xba, 0x05, 0x10, 0x26, 0x2a, 0xe4, 0x87, 0xd7, 0x37, 0xee, 0x62,
+    0x98, 0xf7, 0x7e, 0x0c
+};
+
+int FIPS_selftest_aes_gcm(void)
+{
+    int ret = 0;
+    unsigned char out[128], tag[16];
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+    memset(out, 0, sizeof(out));
+    memset(tag, 0, sizeof(tag));
+    if (!EVP_CipherInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 1))
+        goto err;
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN,
+                             sizeof(gcm_iv), NULL))
+        goto err;
+    if (!EVP_CipherInit_ex(&ctx, NULL, NULL, gcm_key, gcm_iv, 1))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0)
+        goto err;
+    if (EVP_Cipher(&ctx, out, gcm_pt, sizeof(gcm_pt)) != sizeof(gcm_ct))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, NULL, 0) < 0)
+        goto err;
+
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
+        goto err;
+
+    if (memcmp(tag, gcm_tag, 16) || memcmp(out, gcm_ct, 16))
+        goto err;
+
+    memset(out, 0, sizeof(out));
+
+    if (!EVP_CipherInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 0))
+        goto err;
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN,
+                             sizeof(gcm_iv), NULL))
+        goto err;
+    if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, 16, tag))
+        goto err;
+    if (!EVP_CipherInit_ex(&ctx, NULL, NULL, gcm_key, gcm_iv, 0))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0)
+        goto err;
+    if (EVP_Cipher(&ctx, out, gcm_ct, sizeof(gcm_ct)) != sizeof(gcm_pt))
+        goto err;
+    if (EVP_Cipher(&ctx, NULL, NULL, 0) < 0)
+        goto err;
+
+    if (memcmp(out, gcm_pt, 16))
+        goto err;
+
+    ret = 1;
+
+ err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+
+    if (ret == 0) {
+        FIPSerr(FIPS_F_FIPS_SELFTEST_AES_GCM, FIPS_R_SELFTEST_FAILED);
+        return 0;
+    } else
+        return ret;
+
+}
+
+static const unsigned char XTS_128_key[] = {
+    0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35, 0x3b, 0x2c, 0x34, 0x38,
+    0x76, 0x08, 0x17, 0x62, 0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18,
+    0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f
+};
+
+static const unsigned char XTS_128_i[] = {
+    0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6, 0x6e, 0x4b, 0x92, 0x01,
+    0x3e, 0x76, 0x8a, 0xd5
+};
+
+static const unsigned char XTS_128_pt[] = {
+    0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, 0x6f, 0xb3, 0x50, 0x39,
+    0x07, 0x90, 0x31, 0x1c
+};
+
+static const unsigned char XTS_128_ct[] = {
+    0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a, 0x82, 0x50, 0x81, 0xd5,
+    0xbe, 0x47, 0x1c, 0x63
+};
+
+static const unsigned char XTS_256_key[] = {
+    0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e, 0x48, 0x01, 0xe4, 0x2f,
+    0x4b, 0x09, 0x47, 0x14, 0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7,
+    0x50, 0x52, 0x10, 0xbd, 0x31, 0x1a, 0x0e, 0x7c, 0xd6, 0xe1, 0x3f, 0xfd,
+    0xf2, 0x41, 0x8d, 0x8d, 0x19, 0x11, 0xc0, 0x04, 0xcd, 0xa5, 0x8d, 0xa3,
+    0xd6, 0x19, 0xb7, 0xe2, 0xb9, 0x14, 0x1e, 0x58, 0x31, 0x8e, 0xea, 0x39,
+    0x2c, 0xf4, 0x1b, 0x08
+};
+
+static const unsigned char XTS_256_i[] = {
+    0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2, 0xf0, 0x42, 0x8e, 0x84,
+    0xa9, 0xf8, 0x75, 0x64
+};
+
+static const unsigned char XTS_256_pt[] = {
+    0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1, 0xac, 0xc6, 0x47, 0xe8,
+    0x10, 0xbb, 0xc3, 0x64, 0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3,
+    0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e
+};
+
+static const unsigned char XTS_256_ct[] = {
+    0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5, 0x0b, 0x37, 0xf9, 0x34,
+    0xd4, 0x6a, 0x9b, 0x13, 0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a,
+    0xf7, 0x93, 0xe8, 0x6f, 0x73, 0xc6, 0xd7, 0xdb
+};
+
+int FIPS_selftest_aes_xts()
+{
+    int ret = 1;
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+
+    if (fips_cipher_test(&ctx, EVP_aes_128_xts(),
+                         XTS_128_key, XTS_128_i, XTS_128_pt, XTS_128_ct,
+                         sizeof(XTS_128_pt)) <= 0)
+        ret = 0;
+
+    if (fips_cipher_test(&ctx, EVP_aes_256_xts(),
+                         XTS_256_key, XTS_256_i, XTS_256_pt, XTS_256_ct,
+                         sizeof(XTS_256_pt)) <= 0)
+        ret = 0;
+
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    if (ret == 0)
+        FIPSerr(FIPS_F_FIPS_SELFTEST_AES_XTS, FIPS_R_SELFTEST_FAILED);
+    return ret;
+}
+
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips.c.fips openssl-1.0.2i/crypto/fips/fips.c
--- openssl-1.0.2i/crypto/fips/fips.c.fips	2016-09-22 13:35:57.014220928 +0200
+++ openssl-1.0.2i/crypto/fips/fips.c	2016-09-22 13:35:57.014220928 +0200
@@ -0,0 +1,483 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/err.h>
+#include <openssl/bio.h>
+#include <openssl/hmac.h>
+#include <openssl/rsa.h>
+#include <string.h>
+#include <limits.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+# include <openssl/fips.h>
+
+# ifndef PATH_MAX
+#  define PATH_MAX 1024
+# endif
+
+static int fips_selftest_fail = 0;
+static int fips_mode = 0;
+static int fips_started = 0;
+
+static int fips_is_owning_thread(void);
+static int fips_set_owning_thread(void);
+static int fips_clear_owning_thread(void);
+
+# define fips_w_lock()   CRYPTO_w_lock(CRYPTO_LOCK_FIPS)
+# define fips_w_unlock() CRYPTO_w_unlock(CRYPTO_LOCK_FIPS)
+# define fips_r_lock()   CRYPTO_r_lock(CRYPTO_LOCK_FIPS)
+# define fips_r_unlock() CRYPTO_r_unlock(CRYPTO_LOCK_FIPS)
+
+static void fips_set_mode(int onoff)
+{
+    int owning_thread = fips_is_owning_thread();
+
+    if (fips_started) {
+        if (!owning_thread)
+            fips_w_lock();
+        fips_mode = onoff;
+        if (!owning_thread)
+            fips_w_unlock();
+    }
+}
+
+int FIPS_module_mode(void)
+{
+    int ret = 0;
+    int owning_thread = fips_is_owning_thread();
+
+    if (fips_started) {
+        if (!owning_thread)
+            fips_r_lock();
+        ret = fips_mode;
+        if (!owning_thread)
+            fips_r_unlock();
+    }
+    return ret;
+}
+
+int FIPS_selftest_failed(void)
+{
+    int ret = 0;
+    if (fips_started) {
+        int owning_thread = fips_is_owning_thread();
+
+        if (!owning_thread)
+            fips_r_lock();
+        ret = fips_selftest_fail;
+        if (!owning_thread)
+            fips_r_unlock();
+    }
+    return ret;
+}
+
+/* Selftest failure fatal exit routine. This will be called
+ * during *any* cryptographic operation. It has the minimum
+ * overhead possible to avoid too big a performance hit.
+ */
+
+void FIPS_selftest_check(void)
+{
+    if (fips_selftest_fail) {
+        OpenSSLDie(__FILE__, __LINE__, "FATAL FIPS SELFTEST FAILURE");
+    }
+}
+
+void fips_set_selftest_fail(void)
+{
+    fips_selftest_fail = 1;
+}
+
+/* we implement what libfipscheck does ourselves */
+
+static int
+get_library_path(const char *libname, const char *symbolname, char *path,
+                 size_t pathlen)
+{
+    Dl_info info;
+    void *dl, *sym;
+    int rv = -1;
+
+    dl = dlopen(libname, RTLD_LAZY);
+    if (dl == NULL) {
+        return -1;
+    }
+
+    sym = dlsym(dl, symbolname);
+
+    if (sym != NULL && dladdr(sym, &info)) {
+        strncpy(path, info.dli_fname, pathlen - 1);
+        path[pathlen - 1] = '\0';
+        rv = 0;
+    }
+
+    dlclose(dl);
+
+    return rv;
+}
+
+static const char conv[] = "0123456789abcdef";
+
+static char *bin2hex(void *buf, size_t len)
+{
+    char *hex, *p;
+    unsigned char *src = buf;
+
+    hex = malloc(len * 2 + 1);
+    if (hex == NULL)
+        return NULL;
+
+    p = hex;
+
+    while (len > 0) {
+        unsigned c;
+
+        c = *src;
+        src++;
+
+        *p = conv[c >> 4];
+        ++p;
+        *p = conv[c & 0x0f];
+        ++p;
+        --len;
+    }
+    *p = '\0';
+    return hex;
+}
+
+# define HMAC_PREFIX "."
+# define HMAC_SUFFIX ".hmac"
+# define READ_BUFFER_LENGTH 16384
+
+static char *make_hmac_path(const char *origpath)
+{
+    char *path, *p;
+    const char *fn;
+
+    path =
+        malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath));
+    if (path == NULL) {
+        return NULL;
+    }
+
+    fn = strrchr(origpath, '/');
+    if (fn == NULL) {
+        fn = origpath;
+    } else {
+        ++fn;
+    }
+
+    strncpy(path, origpath, fn - origpath);
+    p = path + (fn - origpath);
+    p = stpcpy(p, HMAC_PREFIX);
+    p = stpcpy(p, fn);
+    p = stpcpy(p, HMAC_SUFFIX);
+
+    return path;
+}
+
+static const char hmackey[] = "orboDeJITITejsirpADONivirpUkvarP";
+
+static int compute_file_hmac(const char *path, void **buf, size_t *hmaclen)
+{
+    FILE *f = NULL;
+    int rv = -1;
+    unsigned char rbuf[READ_BUFFER_LENGTH];
+    size_t len;
+    unsigned int hlen;
+    HMAC_CTX c;
+
+    HMAC_CTX_init(&c);
+
+    f = fopen(path, "r");
+
+    if (f == NULL) {
+        goto end;
+    }
+
+    HMAC_Init(&c, hmackey, sizeof(hmackey) - 1, EVP_sha256());
+
+    while ((len = fread(rbuf, 1, sizeof(rbuf), f)) != 0) {
+        HMAC_Update(&c, rbuf, len);
+    }
+
+    len = sizeof(rbuf);
+    /* reuse rbuf for hmac */
+    HMAC_Final(&c, rbuf, &hlen);
+
+    *buf = malloc(hlen);
+    if (*buf == NULL) {
+        goto end;
+    }
+
+    *hmaclen = hlen;
+
+    memcpy(*buf, rbuf, hlen);
+
+    rv = 0;
+ end:
+    HMAC_CTX_cleanup(&c);
+
+    if (f)
+        fclose(f);
+
+    return rv;
+}
+
+static int FIPSCHECK_verify(const char *libname, const char *symbolname)
+{
+    char path[PATH_MAX + 1];
+    int rv;
+    FILE *hf;
+    char *hmacpath, *p;
+    char *hmac = NULL;
+    size_t n;
+
+    rv = get_library_path(libname, symbolname, path, sizeof(path));
+
+    if (rv < 0)
+        return 0;
+
+    hmacpath = make_hmac_path(path);
+    if (hmacpath == NULL)
+        return 0;
+
+    hf = fopen(hmacpath, "r");
+    if (hf == NULL) {
+        free(hmacpath);
+        return 0;
+    }
+
+    if (getline(&hmac, &n, hf) > 0) {
+        void *buf;
+        size_t hmaclen;
+        char *hex;
+
+        if ((p = strchr(hmac, '\n')) != NULL)
+            *p = '\0';
+
+        if (compute_file_hmac(path, &buf, &hmaclen) < 0) {
+            rv = -4;
+            goto end;
+        }
+
+        if ((hex = bin2hex(buf, hmaclen)) == NULL) {
+            free(buf);
+            rv = -5;
+            goto end;
+        }
+
+        if (strcmp(hex, hmac) != 0) {
+            rv = -1;
+        }
+        free(buf);
+        free(hex);
+    } else {
+        rv = -1;
+    }
+
+ end:
+    free(hmac);
+    free(hmacpath);
+    fclose(hf);
+
+    if (rv < 0)
+        return 0;
+
+    /* check successful */
+    return 1;
+}
+
+int FIPS_module_mode_set(int onoff, const char *auth)
+{
+    int ret = 0;
+
+    fips_w_lock();
+    fips_started = 1;
+    fips_set_owning_thread();
+
+    if (onoff) {
+
+        fips_selftest_fail = 0;
+
+        /* Don't go into FIPS mode twice, just so we can do automagic
+           seeding */
+        if (FIPS_module_mode()) {
+            FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,
+                    FIPS_R_FIPS_MODE_ALREADY_SET);
+            fips_selftest_fail = 1;
+            ret = 0;
+            goto end;
+        }
+# ifdef OPENSSL_IA32_SSE2
+        {
+            extern unsigned int OPENSSL_ia32cap_P[2];
+            if ((OPENSSL_ia32cap_P[0] & (1 << 25 | 1 << 26)) !=
+                (1 << 25 | 1 << 26)) {
+                FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,
+                        FIPS_R_UNSUPPORTED_PLATFORM);
+                fips_selftest_fail = 1;
+                ret = 0;
+                goto end;
+            }
+            OPENSSL_ia32cap_P[0] |= (1 << 28); /* set "shared cache"   */
+            OPENSSL_ia32cap_P[1] &= ~(1 << (60 - 32)); /* clear AVX            */
+        }
+# endif
+
+        if (!FIPSCHECK_verify
+            ("libcrypto.so." SHLIB_VERSION_NUMBER, "FIPS_mode_set")) {
+            FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,
+                    FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
+            fips_selftest_fail = 1;
+            ret = 0;
+            goto end;
+        }
+
+        if (!FIPSCHECK_verify
+            ("libssl.so." SHLIB_VERSION_NUMBER, "SSL_CTX_new")) {
+            FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET,
+                    FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
+            fips_selftest_fail = 1;
+            ret = 0;
+            goto end;
+        }
+
+        if (FIPS_selftest())
+            fips_set_mode(onoff);
+        else {
+            fips_selftest_fail = 1;
+            ret = 0;
+            goto end;
+        }
+        ret = 1;
+        goto end;
+    }
+    fips_set_mode(0);
+    fips_selftest_fail = 0;
+    ret = 1;
+ end:
+    fips_clear_owning_thread();
+    fips_w_unlock();
+    return ret;
+}
+
+static CRYPTO_THREADID fips_thread;
+static int fips_thread_set = 0;
+
+static int fips_is_owning_thread(void)
+{
+    int ret = 0;
+
+    if (fips_started) {
+        CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
+        if (fips_thread_set) {
+            CRYPTO_THREADID cur;
+            CRYPTO_THREADID_current(&cur);
+            if (!CRYPTO_THREADID_cmp(&cur, &fips_thread))
+                ret = 1;
+        }
+        CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
+    }
+    return ret;
+}
+
+int fips_set_owning_thread(void)
+{
+    int ret = 0;
+
+    if (fips_started) {
+        CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
+        if (!fips_thread_set) {
+            CRYPTO_THREADID_current(&fips_thread);
+            ret = 1;
+            fips_thread_set = 1;
+        }
+        CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
+    }
+    return ret;
+}
+
+int fips_clear_owning_thread(void)
+{
+    int ret = 0;
+
+    if (fips_started) {
+        CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
+        if (fips_thread_set) {
+            CRYPTO_THREADID cur;
+            CRYPTO_THREADID_current(&cur);
+            if (!CRYPTO_THREADID_cmp(&cur, &fips_thread))
+                fips_thread_set = 0;
+        }
+        CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
+    }
+    return ret;
+}
+
+# if 0
+/* The purpose of this is to ensure the error code exists and the function
+ * name is to keep the error checking script quiet
+ */
+void hash_final(void)
+{
+    FIPSerr(FIPS_F_HASH_FINAL, FIPS_R_NON_FIPS_METHOD);
+}
+# endif
+
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c.fips	2016-09-22 13:35:57.014220928 +0200
+++ openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c	2016-09-22 13:35:57.014220928 +0200
@@ -0,0 +1,156 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/cmac.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+typedef struct {
+    int nid;
+    const unsigned char key[EVP_MAX_KEY_LENGTH];
+    size_t keysize;
+    const unsigned char msg[64];
+    size_t msgsize;
+    const unsigned char mac[32];
+    size_t macsize;
+} CMAC_KAT;
+
+/* from http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf */
+static const CMAC_KAT vector[] = {
+    {NID_aes_128_cbc,           /* Count = 32 from CMACGenAES128.txt */
+     {0x77, 0xa7, 0x7f, 0xaf, 0x29, 0x0c, 0x1f, 0xa3,
+      0x0c, 0x68, 0x3d, 0xf1, 0x6b, 0xa7, 0xa7, 0x7b,}, 128,
+     {0x02, 0x06, 0x83, 0xe1, 0xf0, 0x39, 0x2f, 0x4c,
+      0xac, 0x54, 0x31, 0x8b, 0x60, 0x29, 0x25, 0x9e,
+      0x9c, 0x55, 0x3d, 0xbc, 0x4b, 0x6a, 0xd9, 0x98,
+      0xe6, 0x4d, 0x58, 0xe4, 0xe7, 0xdc, 0x2e, 0x13,}, 256,
+     {0xfb, 0xfe, 0xa4, 0x1b,}, 32},
+    {NID_aes_192_cbc,           /* Count = 23 from CMACGenAES192.txt */
+     {0x7b, 0x32, 0x39, 0x13, 0x69, 0xaa, 0x4c, 0xa9,
+      0x75, 0x58, 0x09, 0x5b, 0xe3, 0xc3, 0xec, 0x86,
+      0x2b, 0xd0, 0x57, 0xce, 0xf1, 0xe3, 0x2d, 0x62,}, 192,
+     {0x0}, 0,
+     {0xe4, 0xd9, 0x34, 0x0b, 0x03, 0xe6, 0x7d, 0xef,
+      0xd4, 0x96, 0x9c, 0xc1, 0xed, 0x37, 0x35, 0xe6,}, 128,
+     },
+    {NID_aes_256_cbc,           /* Count = 33 from CMACGenAES256.txt */
+     {0x0b, 0x12, 0x2a, 0xc8, 0xf3, 0x4e, 0xd1, 0xfe,
+      0x08, 0x2a, 0x36, 0x25, 0xd1, 0x57, 0x56, 0x14,
+      0x54, 0x16, 0x7a, 0xc1, 0x45, 0xa1, 0x0b, 0xbf,
+      0x77, 0xc6, 0xa7, 0x05, 0x96, 0xd5, 0x74, 0xf1,}, 256,
+     {0x49, 0x8b, 0x53, 0xfd, 0xec, 0x87, 0xed, 0xcb,
+      0xf0, 0x70, 0x97, 0xdc, 0xcd, 0xe9, 0x3a, 0x08,
+      0x4b, 0xad, 0x75, 0x01, 0xa2, 0x24, 0xe3, 0x88,
+      0xdf, 0x34, 0x9c, 0xe1, 0x89, 0x59, 0xfe, 0x84,
+      0x85, 0xf8, 0xad, 0x15, 0x37, 0xf0, 0xd8, 0x96,
+      0xea, 0x73, 0xbe, 0xdc, 0x72, 0x14, 0x71, 0x3f,}, 384,
+     {0xf6, 0x2c, 0x46, 0x32, 0x9b,}, 40,
+     },
+    {NID_des_ede3_cbc,          /* Count = 41 from CMACGenTDES3.req */
+     {0x89, 0xbc, 0xd9, 0x52, 0xa8, 0xc8, 0xab, 0x37,
+      0x1a, 0xf4, 0x8a, 0xc7, 0xd0, 0x70, 0x85, 0xd5,
+      0xef, 0xf7, 0x02, 0xe6, 0xd6, 0x2c, 0xdc, 0x23,}, 192,
+     {0xfa, 0x62, 0x0c, 0x1b, 0xbe, 0x97, 0x31, 0x9e,
+      0x9a, 0x0c, 0xf0, 0x49, 0x21, 0x21, 0xf7, 0xa2,
+      0x0e, 0xb0, 0x8a, 0x6a, 0x70, 0x9d, 0xcb, 0xd0,
+      0x0a, 0xaf, 0x38, 0xe4, 0xf9, 0x9e, 0x75, 0x4e,}, 256,
+     {0x8f, 0x49, 0xa1, 0xb7, 0xd6, 0xaa, 0x22, 0x58,}, 64,
+     },
+};
+
+int FIPS_selftest_cmac()
+{
+    size_t n, outlen;
+    unsigned char out[32];
+    const EVP_CIPHER *cipher;
+    CMAC_CTX *ctx = CMAC_CTX_new();
+    const CMAC_KAT *t;
+    int rv = 1;
+
+    for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) {
+        cipher = FIPS_get_cipherbynid(t->nid);
+        if (!cipher) {
+            rv = -1;
+            goto err;
+        }
+        if (!CMAC_Init(ctx, t->key, t->keysize / 8, cipher, 0)) {
+            rv = -1;
+            goto err;
+        }
+        if (!CMAC_Update(ctx, t->msg, t->msgsize / 8)) {
+            rv = -1;
+            goto err;
+        }
+
+        if (!CMAC_Final(ctx, out, &outlen)) {
+            rv = -1;
+            goto err;
+        }
+        CMAC_CTX_cleanup(ctx);
+
+        if (outlen < t->macsize / 8 || memcmp(out, t->mac, t->macsize / 8)) {
+            rv = 0;
+        }
+    }
+
+ err:
+    CMAC_CTX_free(ctx);
+
+    if (rv == -1) {
+        rv = 0;
+    }
+    if (!rv)
+        FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC, FIPS_R_SELFTEST_FAILED);
+
+    return rv;
+}
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_des_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_des_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_des_selftest.c.fips	2016-09-22 13:35:57.014220928 +0200
+++ openssl-1.0.2i/crypto/fips/fips_des_selftest.c	2016-09-22 13:35:57.014220928 +0200
@@ -0,0 +1,138 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+
+static const struct {
+    const unsigned char key[16];
+    const unsigned char plaintext[8];
+    const unsigned char ciphertext[8];
+} tests2[] = {
+    {
+        {
+        0x7c, 0x4f, 0x6e, 0xf7, 0xa2, 0x04, 0x16, 0xec,
+                0x0b, 0x6b, 0x7c, 0x9e, 0x5e, 0x19, 0xa7, 0xc4}, {
+        0x06, 0xa7, 0xd8, 0x79, 0xaa, 0xce, 0x69, 0xef}, {
+        0x4c, 0x11, 0x17, 0x55, 0xbf, 0xc4, 0x4e, 0xfd}
+    }, {
+        {
+        0x5d, 0x9e, 0x01, 0xd3, 0x25, 0xc7, 0x3e, 0x34,
+                0x01, 0x16, 0x7c, 0x85, 0x23, 0xdf, 0xe0, 0x68}, {
+        0x9c, 0x50, 0x09, 0x0f, 0x5e, 0x7d, 0x69, 0x7e}, {
+    0xd2, 0x0b, 0x18, 0xdf, 0xd9, 0x0d, 0x9e, 0xff},}
+};
+
+static const struct {
+    const unsigned char key[24];
+    const unsigned char plaintext[8];
+    const unsigned char ciphertext[8];
+} tests3[] = {
+    {
+        {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+                0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}, {
+        0x8f, 0x8f, 0xbf, 0x9b, 0x5d, 0x48, 0xb4, 0x1c}, {
+    0x59, 0x8c, 0xe5, 0xd3, 0x6c, 0xa2, 0xea, 0x1b},}, {
+        {
+        0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE,
+                0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+                0xED, 0x39, 0xD9, 0x50, 0xFA, 0x74, 0xBC, 0xC4}, {
+        0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, {
+0x11, 0x25, 0xb0, 0x35, 0xbe, 0xa0, 0x82, 0x86},},};
+
+static int corrupt_des;
+
+void FIPS_corrupt_des()
+{
+    corrupt_des = 1;
+}
+
+int FIPS_selftest_des()
+{
+    int n, ret = 0;
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+    /* Encrypt/decrypt with 2-key 3DES and compare to known answers */
+    for (n = 0; n < 2; ++n) {
+        unsigned char plaintext[8];
+
+        memcpy(plaintext, tests2[n].plaintext, sizeof(plaintext));
+        if (corrupt_des)
+            plaintext[0]++;
+        if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(),
+                              tests2[n].key, NULL,
+                              plaintext, tests2[n].ciphertext, 8))
+            goto err;
+    }
+
+    /* Encrypt/decrypt with 3DES and compare to known answers */
+    for (n = 0; n < 2; ++n) {
+        if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(),
+                              tests3[n].key, NULL,
+                              tests3[n].plaintext, tests3[n].ciphertext, 8))
+            goto err;
+    }
+    ret = 1;
+ err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    if (ret == 0)
+        FIPSerr(FIPS_F_FIPS_SELFTEST_DES, FIPS_R_SELFTEST_FAILED);
+
+    return ret;
+}
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c
--- openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c.fips	2016-09-22 13:35:57.014220928 +0200
+++ openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c	2016-09-22 13:35:57.014220928 +0200
@@ -0,0 +1,415 @@
+/* fips/rand/fips_drbg_ctr.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#include "fips_rand_lcl.h"
+
+static void inc_128(DRBG_CTR_CTX * cctx)
+{
+    int i;
+    unsigned char c;
+    unsigned char *p = cctx->V + 15;
+    for (i = 0; i < 16; i++) {
+        c = *p;
+        c++;
+        *p = c;
+        if (c)
+            return;
+        p--;
+    }
+}
+
+static void ctr_XOR(DRBG_CTR_CTX * cctx, const unsigned char *in,
+                    size_t inlen)
+{
+    size_t i, n;
+    /* Any zero padding will have no effect on the result as we
+     * are XORing. So just process however much input we have.
+     */
+
+    if (!in || !inlen)
+        return;
+
+    if (inlen < cctx->keylen)
+        n = inlen;
+    else
+        n = cctx->keylen;
+
+    for (i = 0; i < n; i++)
+        cctx->K[i] ^= in[i];
+    if (inlen <= cctx->keylen)
+        return;
+
+    n = inlen - cctx->keylen;
+    /* Should never happen */
+    if (n > 16)
+        n = 16;
+    for (i = 0; i < 16; i++)
+        cctx->V[i] ^= in[i + cctx->keylen];
+}
+
+/* Process a complete block using BCC algorithm of SPP 800-90 10.4.3 */
+
+static void ctr_BCC_block(DRBG_CTR_CTX * cctx, unsigned char *out,
+                          const unsigned char *in)
+{
+    int i;
+    for (i = 0; i < 16; i++)
+        out[i] ^= in[i];
+    AES_encrypt(out, out, &cctx->df_ks);
+#if 0
+    fprintf(stderr, "BCC in+out\n");
+    BIO_dump_fp(stderr, in, 16);
+    BIO_dump_fp(stderr, out, 16);
+#endif
+}
+
+/* Handle several BCC operations for as much data as we need for K and X */
+static void ctr_BCC_blocks(DRBG_CTR_CTX * cctx, const unsigned char *in)
+{
+    ctr_BCC_block(cctx, cctx->KX, in);
+    ctr_BCC_block(cctx, cctx->KX + 16, in);
+    if (cctx->keylen != 16)
+        ctr_BCC_block(cctx, cctx->KX + 32, in);
+}
+
+/* Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
+ * see 10.4.2 stage 7.
+ */
+static void ctr_BCC_init(DRBG_CTR_CTX * cctx)
+{
+    memset(cctx->KX, 0, 48);
+    memset(cctx->bltmp, 0, 16);
+    ctr_BCC_block(cctx, cctx->KX, cctx->bltmp);
+    cctx->bltmp[3] = 1;
+    ctr_BCC_block(cctx, cctx->KX + 16, cctx->bltmp);
+    if (cctx->keylen != 16) {
+        cctx->bltmp[3] = 2;
+        ctr_BCC_block(cctx, cctx->KX + 32, cctx->bltmp);
+    }
+}
+
+/* Process several blocks into BCC algorithm, some possibly partial */
+static void ctr_BCC_update(DRBG_CTR_CTX * cctx,
+                           const unsigned char *in, size_t inlen)
+{
+    if (!in || !inlen)
+        return;
+    /* If we have partial block handle it first */
+    if (cctx->bltmp_pos) {
+        size_t left = 16 - cctx->bltmp_pos;
+        /* If we now have a complete block process it */
+        if (inlen >= left) {
+            memcpy(cctx->bltmp + cctx->bltmp_pos, in, left);
+            ctr_BCC_blocks(cctx, cctx->bltmp);
+            cctx->bltmp_pos = 0;
+            inlen -= left;
+            in += left;
+        }
+    }
+    /* Process zero or more complete blocks */
+    while (inlen >= 16) {
+        ctr_BCC_blocks(cctx, in);
+        in += 16;
+        inlen -= 16;
+    }
+    /* Copy any remaining partial block to the temporary buffer */
+    if (inlen > 0) {
+        memcpy(cctx->bltmp + cctx->bltmp_pos, in, inlen);
+        cctx->bltmp_pos += inlen;
+    }
+}
+
+static void ctr_BCC_final(DRBG_CTR_CTX * cctx)
+{
+    if (cctx->bltmp_pos) {
+        memset(cctx->bltmp + cctx->bltmp_pos, 0, 16 - cctx->bltmp_pos);
+        ctr_BCC_blocks(cctx, cctx->bltmp);
+    }
+}
+
+static void ctr_df(DRBG_CTR_CTX * cctx,
+                   const unsigned char *in1, size_t in1len,
+                   const unsigned char *in2, size_t in2len,
+                   const unsigned char *in3, size_t in3len)
+{
+    size_t inlen;
+    unsigned char *p = cctx->bltmp;
+    static unsigned char c80 = 0x80;
+
+    ctr_BCC_init(cctx);
+    if (!in1)
+        in1len = 0;
+    if (!in2)
+        in2len = 0;
+    if (!in3)
+        in3len = 0;
+    inlen = in1len + in2len + in3len;
+    /* Initialise L||N in temporary block */
+    *p++ = (inlen >> 24) & 0xff;
+    *p++ = (inlen >> 16) & 0xff;
+    *p++ = (inlen >> 8) & 0xff;
+    *p++ = inlen & 0xff;
+    /* NB keylen is at most 32 bytes */
+    *p++ = 0;
+    *p++ = 0;
+    *p++ = 0;
+    *p = (unsigned char)((cctx->keylen + 16) & 0xff);
+    cctx->bltmp_pos = 8;
+    ctr_BCC_update(cctx, in1, in1len);
+    ctr_BCC_update(cctx, in2, in2len);
+    ctr_BCC_update(cctx, in3, in3len);
+    ctr_BCC_update(cctx, &c80, 1);
+    ctr_BCC_final(cctx);
+    /* Set up key K */
+    AES_set_encrypt_key(cctx->KX, cctx->keylen * 8, &cctx->df_kxks);
+    /* X follows key K */
+    AES_encrypt(cctx->KX + cctx->keylen, cctx->KX, &cctx->df_kxks);
+    AES_encrypt(cctx->KX, cctx->KX + 16, &cctx->df_kxks);
+    if (cctx->keylen != 16)
+        AES_encrypt(cctx->KX + 16, cctx->KX + 32, &cctx->df_kxks);
+#if 0
+    fprintf(stderr, "Output of ctr_df:\n");
+    BIO_dump_fp(stderr, cctx->KX, cctx->keylen + 16);
+#endif
+}
+
+/* NB the no-df  Update in SP800-90 specifies a constant input length
+ * of seedlen, however other uses of this algorithm pad the input with
+ * zeroes if necessary and have up to two parameters XORed together,
+ * handle both cases in this function instead.
+ */
+
+static void ctr_Update(DRBG_CTX *dctx,
+                       const unsigned char *in1, size_t in1len,
+                       const unsigned char *in2, size_t in2len,
+                       const unsigned char *nonce, size_t noncelen)
+{
+    DRBG_CTR_CTX *cctx = &dctx->d.ctr;
+    /* ks is already setup for correct key */
+    inc_128(cctx);
+    AES_encrypt(cctx->V, cctx->K, &cctx->ks);
+    /* If keylen longer than 128 bits need extra encrypt */
+    if (cctx->keylen != 16) {
+        inc_128(cctx);
+        AES_encrypt(cctx->V, cctx->K + 16, &cctx->ks);
+    }
+    inc_128(cctx);
+    AES_encrypt(cctx->V, cctx->V, &cctx->ks);
+    /* If 192 bit key part of V is on end of K */
+    if (cctx->keylen == 24) {
+        memcpy(cctx->V + 8, cctx->V, 8);
+        memcpy(cctx->V, cctx->K + 24, 8);
+    }
+
+    if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) {
+        /* If no input reuse existing derived value */
+        if (in1 || nonce || in2)
+            ctr_df(cctx, in1, in1len, nonce, noncelen, in2, in2len);
+        /* If this a reuse input in1len != 0 */
+        if (in1len)
+            ctr_XOR(cctx, cctx->KX, dctx->seedlen);
+    } else {
+        ctr_XOR(cctx, in1, in1len);
+        ctr_XOR(cctx, in2, in2len);
+    }
+
+    AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks);
+#if 0
+    fprintf(stderr, "K+V after update is:\n");
+    BIO_dump_fp(stderr, cctx->K, cctx->keylen);
+    BIO_dump_fp(stderr, cctx->V, 16);
+#endif
+}
+
+static int drbg_ctr_instantiate(DRBG_CTX *dctx,
+                                const unsigned char *ent, size_t entlen,
+                                const unsigned char *nonce, size_t noncelen,
+                                const unsigned char *pers, size_t perslen)
+{
+    DRBG_CTR_CTX *cctx = &dctx->d.ctr;
+    memset(cctx->K, 0, sizeof(cctx->K));
+    memset(cctx->V, 0, sizeof(cctx->V));
+    AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks);
+    ctr_Update(dctx, ent, entlen, pers, perslen, nonce, noncelen);
+    return 1;
+}
+
+static int drbg_ctr_reseed(DRBG_CTX *dctx,
+                           const unsigned char *ent, size_t entlen,
+                           const unsigned char *adin, size_t adinlen)
+{
+    ctr_Update(dctx, ent, entlen, adin, adinlen, NULL, 0);
+    return 1;
+}
+
+static int drbg_ctr_generate(DRBG_CTX *dctx,
+                             unsigned char *out, size_t outlen,
+                             const unsigned char *adin, size_t adinlen)
+{
+    DRBG_CTR_CTX *cctx = &dctx->d.ctr;
+    if (adin && adinlen) {
+        ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0);
+        /* This means we reuse derived value */
+        if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) {
+            adin = NULL;
+            adinlen = 1;
+        }
+    } else
+        adinlen = 0;
+
+    for (;;) {
+        inc_128(cctx);
+        if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) {
+            AES_encrypt(cctx->V, dctx->lb, &cctx->ks);
+            dctx->lb_valid = 1;
+            continue;
+        }
+        if (outlen < 16) {
+            /* Use K as temp space as it will be updated */
+            AES_encrypt(cctx->V, cctx->K, &cctx->ks);
+            if (!fips_drbg_cprng_test(dctx, cctx->K))
+                return 0;
+            memcpy(out, cctx->K, outlen);
+            break;
+        }
+        AES_encrypt(cctx->V, out, &cctx->ks);
+        if (!fips_drbg_cprng_test(dctx, out))
+            return 0;
+        out += 16;
+        outlen -= 16;
+        if (outlen == 0)
+            break;
+    }
+
+    ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0);
+
+    return 1;
+
+}
+
+static int drbg_ctr_uninstantiate(DRBG_CTX *dctx)
+{
+    memset(&dctx->d.ctr, 0, sizeof(DRBG_CTR_CTX));
+    return 1;
+}
+
+int fips_drbg_ctr_init(DRBG_CTX *dctx)
+{
+    DRBG_CTR_CTX *cctx = &dctx->d.ctr;
+
+    size_t keylen;
+
+    switch (dctx->type) {
+    case NID_aes_128_ctr:
+        keylen = 16;
+        break;
+
+    case NID_aes_192_ctr:
+        keylen = 24;
+        break;
+
+    case NID_aes_256_ctr:
+        keylen = 32;
+        break;
+
+    default:
+        return -2;
+    }
+
+    dctx->instantiate = drbg_ctr_instantiate;
+    dctx->reseed = drbg_ctr_reseed;
+    dctx->generate = drbg_ctr_generate;
+    dctx->uninstantiate = drbg_ctr_uninstantiate;
+
+    cctx->keylen = keylen;
+    dctx->strength = keylen * 8;
+    dctx->blocklength = 16;
+    dctx->seedlen = keylen + 16;
+
+    if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) {
+        /* df initialisation */
+        static unsigned char df_key[32] = {
+            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
+        };
+        /* Set key schedule for df_key */
+        AES_set_encrypt_key(df_key, dctx->strength, &cctx->df_ks);
+
+        dctx->min_entropy = cctx->keylen;
+        dctx->max_entropy = DRBG_MAX_LENGTH;
+        dctx->min_nonce = dctx->min_entropy / 2;
+        dctx->max_nonce = DRBG_MAX_LENGTH;
+        dctx->max_pers = DRBG_MAX_LENGTH;
+        dctx->max_adin = DRBG_MAX_LENGTH;
+    } else {
+        dctx->min_entropy = dctx->seedlen;
+        dctx->max_entropy = dctx->seedlen;
+        /* Nonce not used */
+        dctx->min_nonce = 0;
+        dctx->max_nonce = 0;
+        dctx->max_pers = dctx->seedlen;
+        dctx->max_adin = dctx->seedlen;
+    }
+
+    dctx->max_request = 1 << 16;
+    dctx->reseed_interval = 1 << 24;
+
+    return 1;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_drbg_hash.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_hash.c
--- openssl-1.0.2i/crypto/fips/fips_drbg_hash.c.fips	2016-09-22 13:35:57.014220928 +0200
+++ openssl-1.0.2i/crypto/fips/fips_drbg_hash.c	2016-09-22 13:35:57.014220928 +0200
@@ -0,0 +1,358 @@
+/* fips/rand/fips_drbg_hash.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#include "fips_rand_lcl.h"
+
+/* This is Hash_df from SP 800-90 10.4.1 */
+
+static int hash_df(DRBG_CTX *dctx, unsigned char *out,
+                   const unsigned char *in1, size_t in1len,
+                   const unsigned char *in2, size_t in2len,
+                   const unsigned char *in3, size_t in3len,
+                   const unsigned char *in4, size_t in4len)
+{
+    EVP_MD_CTX *mctx = &dctx->d.hash.mctx;
+    unsigned char *vtmp = dctx->d.hash.vtmp;
+    unsigned char tmp[6];
+    /* Standard only ever needs seedlen bytes which is always less than
+     * maximum permitted so no need to check length.
+     */
+    size_t outlen = dctx->seedlen;
+    tmp[0] = 1;
+    tmp[1] = ((outlen * 8) >> 24) & 0xff;
+    tmp[2] = ((outlen * 8) >> 16) & 0xff;
+    tmp[3] = ((outlen * 8) >> 8) & 0xff;
+    tmp[4] = (outlen * 8) & 0xff;
+    if (!in1) {
+        tmp[5] = (unsigned char)in1len;
+        in1 = tmp + 5;
+        in1len = 1;
+    }
+    for (;;) {
+        if (!FIPS_digestinit(mctx, dctx->d.hash.md))
+            return 0;
+        if (!FIPS_digestupdate(mctx, tmp, 5))
+            return 0;
+        if (in1 && !FIPS_digestupdate(mctx, in1, in1len))
+            return 0;
+        if (in2 && !FIPS_digestupdate(mctx, in2, in2len))
+            return 0;
+        if (in3 && !FIPS_digestupdate(mctx, in3, in3len))
+            return 0;
+        if (in4 && !FIPS_digestupdate(mctx, in4, in4len))
+            return 0;
+        if (outlen < dctx->blocklength) {
+            if (!FIPS_digestfinal(mctx, vtmp, NULL))
+                return 0;
+            memcpy(out, vtmp, outlen);
+            OPENSSL_cleanse(vtmp, dctx->blocklength);
+            return 1;
+        } else if (!FIPS_digestfinal(mctx, out, NULL))
+            return 0;
+
+        outlen -= dctx->blocklength;
+        if (outlen == 0)
+            return 1;
+        tmp[0]++;
+        out += dctx->blocklength;
+    }
+}
+
+/* Add an unsigned buffer to the buf value, storing the result in buf. For
+ * this algorithm the length of input never exceeds the seed length.
+ */
+
+static void ctx_add_buf(DRBG_CTX *dctx, unsigned char *buf,
+                        unsigned char *in, size_t inlen)
+{
+    size_t i = inlen;
+    const unsigned char *q;
+    unsigned char c, *p;
+    p = buf + dctx->seedlen;
+    q = in + inlen;
+
+    OPENSSL_assert(i <= dctx->seedlen);
+
+    /* Special case: zero length, just increment buffer */
+    if (i)
+        c = 0;
+    else
+        c = 1;
+
+    while (i) {
+        int r;
+        p--;
+        q--;
+        r = *p + *q + c;
+        /* Carry */
+        if (r > 0xff)
+            c = 1;
+        else
+            c = 0;
+        *p = r & 0xff;
+        i--;
+    }
+
+    i = dctx->seedlen - inlen;
+
+    /* If not adding whole buffer handle final carries */
+    if (c && i) {
+        do {
+            p--;
+            c = *p;
+            c++;
+            *p = c;
+            if (c)
+                return;
+        } while (i--);
+    }
+}
+
+/* Finalise and add hash to V */
+
+static int ctx_add_md(DRBG_CTX *dctx)
+{
+    if (!FIPS_digestfinal(&dctx->d.hash.mctx, dctx->d.hash.vtmp, NULL))
+        return 0;
+    ctx_add_buf(dctx, dctx->d.hash.V, dctx->d.hash.vtmp, dctx->blocklength);
+    return 1;
+}
+
+static int hash_gen(DRBG_CTX *dctx, unsigned char *out, size_t outlen)
+{
+    DRBG_HASH_CTX *hctx = &dctx->d.hash;
+    if (outlen == 0)
+        return 1;
+    memcpy(hctx->vtmp, hctx->V, dctx->seedlen);
+    for (;;) {
+        FIPS_digestinit(&hctx->mctx, hctx->md);
+        FIPS_digestupdate(&hctx->mctx, hctx->vtmp, dctx->seedlen);
+        if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) {
+            FIPS_digestfinal(&hctx->mctx, dctx->lb, NULL);
+            dctx->lb_valid = 1;
+        } else if (outlen < dctx->blocklength) {
+            FIPS_digestfinal(&hctx->mctx, hctx->vtmp, NULL);
+            if (!fips_drbg_cprng_test(dctx, hctx->vtmp))
+                return 0;
+            memcpy(out, hctx->vtmp, outlen);
+            return 1;
+        } else {
+            FIPS_digestfinal(&hctx->mctx, out, NULL);
+            if (!fips_drbg_cprng_test(dctx, out))
+                return 0;
+            outlen -= dctx->blocklength;
+            if (outlen == 0)
+                return 1;
+            out += dctx->blocklength;
+        }
+        ctx_add_buf(dctx, hctx->vtmp, NULL, 0);
+    }
+}
+
+static int drbg_hash_instantiate(DRBG_CTX *dctx,
+                                 const unsigned char *ent, size_t ent_len,
+                                 const unsigned char *nonce, size_t nonce_len,
+                                 const unsigned char *pstr, size_t pstr_len)
+{
+    DRBG_HASH_CTX *hctx = &dctx->d.hash;
+    if (!hash_df(dctx, hctx->V,
+                 ent, ent_len, nonce, nonce_len, pstr, pstr_len, NULL, 0))
+        return 0;
+    if (!hash_df(dctx, hctx->C,
+                 NULL, 0, hctx->V, dctx->seedlen, NULL, 0, NULL, 0))
+        return 0;
+
+#ifdef HASH_DRBG_TRACE
+    fprintf(stderr, "V+C after instantiate:\n");
+    hexprint(stderr, hctx->V, dctx->seedlen);
+    hexprint(stderr, hctx->C, dctx->seedlen);
+#endif
+    return 1;
+}
+
+static int drbg_hash_reseed(DRBG_CTX *dctx,
+                            const unsigned char *ent, size_t ent_len,
+                            const unsigned char *adin, size_t adin_len)
+{
+    DRBG_HASH_CTX *hctx = &dctx->d.hash;
+    /* V about to be updated so use C as output instead */
+    if (!hash_df(dctx, hctx->C,
+                 NULL, 1, hctx->V, dctx->seedlen,
+                 ent, ent_len, adin, adin_len))
+        return 0;
+    memcpy(hctx->V, hctx->C, dctx->seedlen);
+    if (!hash_df(dctx, hctx->C, NULL, 0,
+                 hctx->V, dctx->seedlen, NULL, 0, NULL, 0))
+        return 0;
+#ifdef HASH_DRBG_TRACE
+    fprintf(stderr, "V+C after reseed:\n");
+    hexprint(stderr, hctx->V, dctx->seedlen);
+    hexprint(stderr, hctx->C, dctx->seedlen);
+#endif
+    return 1;
+}
+
+static int drbg_hash_generate(DRBG_CTX *dctx,
+                              unsigned char *out, size_t outlen,
+                              const unsigned char *adin, size_t adin_len)
+{
+    DRBG_HASH_CTX *hctx = &dctx->d.hash;
+    EVP_MD_CTX *mctx = &hctx->mctx;
+    unsigned char tmp[4];
+    if (adin && adin_len) {
+        tmp[0] = 2;
+        if (!FIPS_digestinit(mctx, hctx->md))
+            return 0;
+        if (!EVP_DigestUpdate(mctx, tmp, 1))
+            return 0;
+        if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen))
+            return 0;
+        if (!EVP_DigestUpdate(mctx, adin, adin_len))
+            return 0;
+        if (!ctx_add_md(dctx))
+            return 0;
+    }
+    if (!hash_gen(dctx, out, outlen))
+        return 0;
+
+    tmp[0] = 3;
+    if (!FIPS_digestinit(mctx, hctx->md))
+        return 0;
+    if (!EVP_DigestUpdate(mctx, tmp, 1))
+        return 0;
+    if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen))
+        return 0;
+
+    if (!ctx_add_md(dctx))
+        return 0;
+
+    ctx_add_buf(dctx, hctx->V, hctx->C, dctx->seedlen);
+
+    tmp[0] = (dctx->reseed_counter >> 24) & 0xff;
+    tmp[1] = (dctx->reseed_counter >> 16) & 0xff;
+    tmp[2] = (dctx->reseed_counter >> 8) & 0xff;
+    tmp[3] = dctx->reseed_counter & 0xff;
+    ctx_add_buf(dctx, hctx->V, tmp, 4);
+#ifdef HASH_DRBG_TRACE
+    fprintf(stderr, "V+C after generate:\n");
+    hexprint(stderr, hctx->V, dctx->seedlen);
+    hexprint(stderr, hctx->C, dctx->seedlen);
+#endif
+    return 1;
+}
+
+static int drbg_hash_uninstantiate(DRBG_CTX *dctx)
+{
+    EVP_MD_CTX_cleanup(&dctx->d.hash.mctx);
+    OPENSSL_cleanse(&dctx->d.hash, sizeof(DRBG_HASH_CTX));
+    return 1;
+}
+
+int fips_drbg_hash_init(DRBG_CTX *dctx)
+{
+    const EVP_MD *md;
+    DRBG_HASH_CTX *hctx = &dctx->d.hash;
+    md = FIPS_get_digestbynid(dctx->type);
+    if (!md)
+        return -2;
+    switch (dctx->type) {
+    case NID_sha1:
+        dctx->strength = 128;
+        break;
+
+    case NID_sha224:
+        dctx->strength = 192;
+        break;
+
+    default:
+        dctx->strength = 256;
+        break;
+    }
+
+    dctx->instantiate = drbg_hash_instantiate;
+    dctx->reseed = drbg_hash_reseed;
+    dctx->generate = drbg_hash_generate;
+    dctx->uninstantiate = drbg_hash_uninstantiate;
+
+    dctx->d.hash.md = md;
+    EVP_MD_CTX_init(&hctx->mctx);
+
+    /* These are taken from SP 800-90 10.1 table 2 */
+
+    dctx->blocklength = M_EVP_MD_size(md);
+    if (dctx->blocklength > 32)
+        dctx->seedlen = 111;
+    else
+        dctx->seedlen = 55;
+
+    dctx->min_entropy = dctx->strength / 8;
+    dctx->max_entropy = DRBG_MAX_LENGTH;
+
+    dctx->min_nonce = dctx->min_entropy / 2;
+    dctx->max_nonce = DRBG_MAX_LENGTH;
+
+    dctx->max_pers = DRBG_MAX_LENGTH;
+    dctx->max_adin = DRBG_MAX_LENGTH;
+
+    dctx->max_request = 1 << 16;
+    dctx->reseed_interval = 1 << 24;
+
+    return 1;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c
--- openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c.fips	2016-09-22 13:35:57.015220951 +0200
+++ openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c	2016-09-22 13:35:57.015220951 +0200
@@ -0,0 +1,270 @@
+/* fips/rand/fips_drbg_hmac.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/aes.h>
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#include "fips_rand_lcl.h"
+
+static int drbg_hmac_update(DRBG_CTX *dctx,
+                            const unsigned char *in1, size_t in1len,
+                            const unsigned char *in2, size_t in2len,
+                            const unsigned char *in3, size_t in3len)
+{
+    static unsigned char c0 = 0, c1 = 1;
+    DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+    HMAC_CTX *hctx = &hmac->hctx;
+
+    if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+        return 0;
+    if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+        return 0;
+    if (!HMAC_Update(hctx, &c0, 1))
+        return 0;
+    if (in1len && !HMAC_Update(hctx, in1, in1len))
+        return 0;
+    if (in2len && !HMAC_Update(hctx, in2, in2len))
+        return 0;
+    if (in3len && !HMAC_Update(hctx, in3, in3len))
+        return 0;
+
+    if (!HMAC_Final(hctx, hmac->K, NULL))
+        return 0;
+
+    if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+        return 0;
+    if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+        return 0;
+
+    if (!HMAC_Final(hctx, hmac->V, NULL))
+        return 0;
+
+    if (!in1len && !in2len && !in3len)
+        return 1;
+
+    if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+        return 0;
+    if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+        return 0;
+    if (!HMAC_Update(hctx, &c1, 1))
+        return 0;
+    if (in1len && !HMAC_Update(hctx, in1, in1len))
+        return 0;
+    if (in2len && !HMAC_Update(hctx, in2, in2len))
+        return 0;
+    if (in3len && !HMAC_Update(hctx, in3, in3len))
+        return 0;
+
+    if (!HMAC_Final(hctx, hmac->K, NULL))
+        return 0;
+
+    if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+        return 0;
+    if (!HMAC_Update(hctx, hmac->V, dctx->blocklength))
+        return 0;
+
+    if (!HMAC_Final(hctx, hmac->V, NULL))
+        return 0;
+
+    return 1;
+
+}
+
+static int drbg_hmac_instantiate(DRBG_CTX *dctx,
+                                 const unsigned char *ent, size_t ent_len,
+                                 const unsigned char *nonce, size_t nonce_len,
+                                 const unsigned char *pstr, size_t pstr_len)
+{
+    DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+    memset(hmac->K, 0, dctx->blocklength);
+    memset(hmac->V, 1, dctx->blocklength);
+    if (!drbg_hmac_update(dctx,
+                          ent, ent_len, nonce, nonce_len, pstr, pstr_len))
+        return 0;
+
+#ifdef HMAC_DRBG_TRACE
+    fprintf(stderr, "K+V after instantiate:\n");
+    hexprint(stderr, hmac->K, hmac->blocklength);
+    hexprint(stderr, hmac->V, hmac->blocklength);
+#endif
+    return 1;
+}
+
+static int drbg_hmac_reseed(DRBG_CTX *dctx,
+                            const unsigned char *ent, size_t ent_len,
+                            const unsigned char *adin, size_t adin_len)
+{
+    if (!drbg_hmac_update(dctx, ent, ent_len, adin, adin_len, NULL, 0))
+        return 0;
+
+#ifdef HMAC_DRBG_TRACE
+    {
+        DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+        fprintf(stderr, "K+V after reseed:\n");
+        hexprint(stderr, hmac->K, hmac->blocklength);
+        hexprint(stderr, hmac->V, hmac->blocklength);
+    }
+#endif
+    return 1;
+}
+
+static int drbg_hmac_generate(DRBG_CTX *dctx,
+                              unsigned char *out, size_t outlen,
+                              const unsigned char *adin, size_t adin_len)
+{
+    DRBG_HMAC_CTX *hmac = &dctx->d.hmac;
+    HMAC_CTX *hctx = &hmac->hctx;
+    const unsigned char *Vtmp = hmac->V;
+    if (adin_len && !drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0))
+        return 0;
+    for (;;) {
+        if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL))
+            return 0;
+        if (!HMAC_Update(hctx, Vtmp, dctx->blocklength))
+            return 0;
+        if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) {
+            if (!HMAC_Final(hctx, dctx->lb, NULL))
+                return 0;
+            dctx->lb_valid = 1;
+            Vtmp = dctx->lb;
+            continue;
+        } else if (outlen > dctx->blocklength) {
+            if (!HMAC_Final(hctx, out, NULL))
+                return 0;
+            if (!fips_drbg_cprng_test(dctx, out))
+                return 0;
+            Vtmp = out;
+        } else {
+            if (!HMAC_Final(hctx, hmac->V, NULL))
+                return 0;
+            if (!fips_drbg_cprng_test(dctx, hmac->V))
+                return 0;
+            memcpy(out, hmac->V, outlen);
+            break;
+        }
+        out += dctx->blocklength;
+        outlen -= dctx->blocklength;
+    }
+    if (!drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0))
+        return 0;
+
+    return 1;
+}
+
+static int drbg_hmac_uninstantiate(DRBG_CTX *dctx)
+{
+    HMAC_CTX_cleanup(&dctx->d.hmac.hctx);
+    OPENSSL_cleanse(&dctx->d.hmac, sizeof(DRBG_HMAC_CTX));
+    return 1;
+}
+
+int fips_drbg_hmac_init(DRBG_CTX *dctx)
+{
+    const EVP_MD *md = NULL;
+    DRBG_HMAC_CTX *hctx = &dctx->d.hmac;
+    dctx->strength = 256;
+    switch (dctx->type) {
+    case NID_hmacWithSHA1:
+        md = EVP_sha1();
+        dctx->strength = 128;
+        break;
+
+    case NID_hmacWithSHA224:
+        md = EVP_sha224();
+        dctx->strength = 192;
+        break;
+
+    case NID_hmacWithSHA256:
+        md = EVP_sha256();
+        break;
+
+    case NID_hmacWithSHA384:
+        md = EVP_sha384();
+        break;
+
+    case NID_hmacWithSHA512:
+        md = EVP_sha512();
+        break;
+
+    default:
+        dctx->strength = 0;
+        return -2;
+    }
+    dctx->instantiate = drbg_hmac_instantiate;
+    dctx->reseed = drbg_hmac_reseed;
+    dctx->generate = drbg_hmac_generate;
+    dctx->uninstantiate = drbg_hmac_uninstantiate;
+    HMAC_CTX_init(&hctx->hctx);
+    hctx->md = md;
+    dctx->blocklength = M_EVP_MD_size(md);
+    dctx->seedlen = M_EVP_MD_size(md);
+
+    dctx->min_entropy = dctx->strength / 8;
+    dctx->max_entropy = DRBG_MAX_LENGTH;
+
+    dctx->min_nonce = dctx->min_entropy / 2;
+    dctx->max_nonce = DRBG_MAX_LENGTH;
+
+    dctx->max_pers = DRBG_MAX_LENGTH;
+    dctx->max_adin = DRBG_MAX_LENGTH;
+
+    dctx->max_request = 1 << 16;
+    dctx->reseed_interval = 1 << 24;
+
+    return 1;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_drbg_lib.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_lib.c
--- openssl-1.0.2i/crypto/fips/fips_drbg_lib.c.fips	2016-09-22 13:35:57.015220951 +0200
+++ openssl-1.0.2i/crypto/fips/fips_drbg_lib.c	2016-09-22 13:35:57.015220951 +0200
@@ -0,0 +1,553 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/fips_rand.h>
+#include "fips_locl.h"
+#include "fips_rand_lcl.h"
+
+/* Support framework for SP800-90 DRBGs */
+
+int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags)
+{
+    int rv;
+    memset(dctx, 0, sizeof(DRBG_CTX));
+    dctx->status = DRBG_STATUS_UNINITIALISED;
+    dctx->xflags = flags;
+    dctx->type = type;
+
+    dctx->iflags = 0;
+    dctx->entropy_blocklen = 0;
+    dctx->health_check_cnt = 0;
+    dctx->health_check_interval = DRBG_HEALTH_INTERVAL;
+
+    rv = fips_drbg_hash_init(dctx);
+
+    if (rv == -2)
+        rv = fips_drbg_ctr_init(dctx);
+    if (rv == -2)
+        rv = fips_drbg_hmac_init(dctx);
+
+    if (rv <= 0) {
+        if (rv == -2)
+            FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_UNSUPPORTED_DRBG_TYPE);
+        else
+            FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_ERROR_INITIALISING_DRBG);
+    }
+
+    /* If not in test mode run selftests on DRBG of the same type */
+
+    if (!(dctx->xflags & DRBG_FLAG_TEST)) {
+        if (!FIPS_drbg_health_check(dctx)) {
+            FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_SELFTEST_FAILURE);
+            return 0;
+        }
+    }
+
+    return rv;
+}
+
+DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags)
+{
+    DRBG_CTX *dctx;
+    dctx = OPENSSL_malloc(sizeof(DRBG_CTX));
+    if (!dctx) {
+        FIPSerr(FIPS_F_FIPS_DRBG_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (type == 0) {
+        memset(dctx, 0, sizeof(DRBG_CTX));
+        dctx->type = 0;
+        dctx->status = DRBG_STATUS_UNINITIALISED;
+        return dctx;
+    }
+
+    if (FIPS_drbg_init(dctx, type, flags) <= 0) {
+        OPENSSL_free(dctx);
+        return NULL;
+    }
+
+    return dctx;
+}
+
+void FIPS_drbg_free(DRBG_CTX *dctx)
+{
+    if (dctx->uninstantiate)
+        dctx->uninstantiate(dctx);
+    /* Don't free up default DRBG */
+    if (dctx == FIPS_get_default_drbg()) {
+        memset(dctx, 0, sizeof(DRBG_CTX));
+        dctx->type = 0;
+        dctx->status = DRBG_STATUS_UNINITIALISED;
+    } else {
+        OPENSSL_cleanse(&dctx->d, sizeof(dctx->d));
+        OPENSSL_free(dctx);
+    }
+}
+
+static size_t fips_get_entropy(DRBG_CTX *dctx, unsigned char **pout,
+                               int entropy, size_t min_len, size_t max_len)
+{
+    unsigned char *tout, *p;
+    size_t bl = dctx->entropy_blocklen, rv;
+    if (!dctx->get_entropy)
+        return 0;
+    if (dctx->xflags & DRBG_FLAG_TEST || !bl)
+        return dctx->get_entropy(dctx, pout, entropy, min_len, max_len);
+    rv = dctx->get_entropy(dctx, &tout, entropy + bl,
+                           min_len + bl, max_len + bl);
+    if (tout == NULL)
+        return 0;
+    *pout = tout + bl;
+    if (rv < (min_len + bl) || (rv % bl))
+        return 0;
+    /* Compare consecutive blocks for continuous PRNG test */
+    for (p = tout; p < tout + rv - bl; p += bl) {
+        if (!memcmp(p, p + bl, bl)) {
+            FIPSerr(FIPS_F_FIPS_GET_ENTROPY, FIPS_R_ENTROPY_SOURCE_STUCK);
+            return 0;
+        }
+    }
+    rv -= bl;
+    if (rv > max_len)
+        return max_len;
+    return rv;
+}
+
+static void fips_cleanup_entropy(DRBG_CTX *dctx,
+                                 unsigned char *out, size_t olen)
+{
+    size_t bl;
+    if (dctx->xflags & DRBG_FLAG_TEST)
+        bl = 0;
+    else
+        bl = dctx->entropy_blocklen;
+    /* Call cleanup with original arguments */
+    dctx->cleanup_entropy(dctx, out - bl, olen + bl);
+}
+
+int FIPS_drbg_instantiate(DRBG_CTX *dctx,
+                          const unsigned char *pers, size_t perslen)
+{
+    size_t entlen = 0, noncelen = 0;
+    unsigned char *nonce = NULL, *entropy = NULL;
+
+#if 0
+    /* Put here so error script picks them up */
+    FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE,
+            FIPS_R_PERSONALISATION_STRING_TOO_LONG);
+    FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_IN_ERROR_STATE);
+    FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ALREADY_INSTANTIATED);
+    FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_ENTROPY);
+    FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_NONCE);
+    FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_INSTANTIATE_ERROR);
+    FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_DRBG_NOT_INITIALISED);
+#endif
+
+    int r = 0;
+
+    if (perslen > dctx->max_pers) {
+        r = FIPS_R_PERSONALISATION_STRING_TOO_LONG;
+        goto end;
+    }
+
+    if (!dctx->instantiate) {
+        r = FIPS_R_DRBG_NOT_INITIALISED;
+        goto end;
+    }
+
+    if (dctx->status != DRBG_STATUS_UNINITIALISED) {
+        if (dctx->status == DRBG_STATUS_ERROR)
+            r = FIPS_R_IN_ERROR_STATE;
+        else
+            r = FIPS_R_ALREADY_INSTANTIATED;
+        goto end;
+    }
+
+    dctx->status = DRBG_STATUS_ERROR;
+
+    entlen = fips_get_entropy(dctx, &entropy, dctx->strength,
+                              dctx->min_entropy, dctx->max_entropy);
+
+    if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) {
+        r = FIPS_R_ERROR_RETRIEVING_ENTROPY;
+        goto end;
+    }
+
+    if (dctx->max_nonce > 0 && dctx->get_nonce) {
+        noncelen = dctx->get_nonce(dctx, &nonce,
+                                   dctx->strength / 2,
+                                   dctx->min_nonce, dctx->max_nonce);
+
+        if (noncelen < dctx->min_nonce || noncelen > dctx->max_nonce) {
+            r = FIPS_R_ERROR_RETRIEVING_NONCE;
+            goto end;
+        }
+
+    }
+
+    if (!dctx->instantiate(dctx,
+                           entropy, entlen, nonce, noncelen, pers, perslen)) {
+        r = FIPS_R_ERROR_INSTANTIATING_DRBG;
+        goto end;
+    }
+
+    dctx->status = DRBG_STATUS_READY;
+    if (!(dctx->iflags & DRBG_CUSTOM_RESEED))
+        dctx->reseed_counter = 1;
+
+ end:
+
+    if (entropy && dctx->cleanup_entropy)
+        fips_cleanup_entropy(dctx, entropy, entlen);
+
+    if (nonce && dctx->cleanup_nonce)
+        dctx->cleanup_nonce(dctx, nonce, noncelen);
+
+    if (dctx->status == DRBG_STATUS_READY)
+        return 1;
+
+    if (r && !(dctx->iflags & DRBG_FLAG_NOERR))
+        FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, r);
+
+    return 0;
+
+}
+
+static int drbg_reseed(DRBG_CTX *dctx,
+                       const unsigned char *adin, size_t adinlen, int hcheck)
+{
+    unsigned char *entropy = NULL;
+    size_t entlen = 0;
+    int r = 0;
+
+#if 0
+    FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_NOT_INSTANTIATED);
+    FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_ADDITIONAL_INPUT_TOO_LONG);
+#endif
+    if (dctx->status != DRBG_STATUS_READY
+        && dctx->status != DRBG_STATUS_RESEED) {
+        if (dctx->status == DRBG_STATUS_ERROR)
+            r = FIPS_R_IN_ERROR_STATE;
+        else if (dctx->status == DRBG_STATUS_UNINITIALISED)
+            r = FIPS_R_NOT_INSTANTIATED;
+        goto end;
+    }
+
+    if (!adin)
+        adinlen = 0;
+    else if (adinlen > dctx->max_adin) {
+        r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG;
+        goto end;
+    }
+
+    dctx->status = DRBG_STATUS_ERROR;
+    /* Peform health check on all reseed operations if not a prediction
+     * resistance request and not in test mode.
+     */
+    if (hcheck && !(dctx->xflags & DRBG_FLAG_TEST)) {
+        if (!FIPS_drbg_health_check(dctx)) {
+            r = FIPS_R_SELFTEST_FAILURE;
+            goto end;
+        }
+    }
+
+    entlen = fips_get_entropy(dctx, &entropy, dctx->strength,
+                              dctx->min_entropy, dctx->max_entropy);
+
+    if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) {
+        r = FIPS_R_ERROR_RETRIEVING_ENTROPY;
+        goto end;
+    }
+
+    if (!dctx->reseed(dctx, entropy, entlen, adin, adinlen))
+        goto end;
+
+    dctx->status = DRBG_STATUS_READY;
+    if (!(dctx->iflags & DRBG_CUSTOM_RESEED))
+        dctx->reseed_counter = 1;
+ end:
+
+    if (entropy && dctx->cleanup_entropy)
+        fips_cleanup_entropy(dctx, entropy, entlen);
+
+    if (dctx->status == DRBG_STATUS_READY)
+        return 1;
+
+    if (r && !(dctx->iflags & DRBG_FLAG_NOERR))
+        FIPSerr(FIPS_F_DRBG_RESEED, r);
+
+    return 0;
+}
+
+int FIPS_drbg_reseed(DRBG_CTX *dctx,
+                     const unsigned char *adin, size_t adinlen)
+{
+    return drbg_reseed(dctx, adin, adinlen, 1);
+}
+
+static int fips_drbg_check(DRBG_CTX *dctx)
+{
+    if (dctx->xflags & DRBG_FLAG_TEST)
+        return 1;
+    dctx->health_check_cnt++;
+    if (dctx->health_check_cnt >= dctx->health_check_interval) {
+        if (!FIPS_drbg_health_check(dctx)) {
+            FIPSerr(FIPS_F_FIPS_DRBG_CHECK, FIPS_R_SELFTEST_FAILURE);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
+                       int prediction_resistance,
+                       const unsigned char *adin, size_t adinlen)
+{
+    int r = 0;
+
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, FIPS_R_SELFTEST_FAILED);
+        return 0;
+    }
+
+    if (!fips_drbg_check(dctx))
+        return 0;
+
+    if (dctx->status != DRBG_STATUS_READY
+        && dctx->status != DRBG_STATUS_RESEED) {
+        if (dctx->status == DRBG_STATUS_ERROR)
+            r = FIPS_R_IN_ERROR_STATE;
+        else if (dctx->status == DRBG_STATUS_UNINITIALISED)
+            r = FIPS_R_NOT_INSTANTIATED;
+        goto end;
+    }
+
+    if (outlen > dctx->max_request) {
+        r = FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG;
+        return 0;
+    }
+
+    if (adinlen > dctx->max_adin) {
+        r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG;
+        goto end;
+    }
+
+    if (dctx->iflags & DRBG_CUSTOM_RESEED)
+        dctx->generate(dctx, NULL, outlen, NULL, 0);
+    else if (dctx->reseed_counter >= dctx->reseed_interval)
+        dctx->status = DRBG_STATUS_RESEED;
+
+    if (dctx->status == DRBG_STATUS_RESEED || prediction_resistance) {
+        /* If prediction resistance request don't do health check */
+        int hcheck = prediction_resistance ? 0 : 1;
+
+        if (!drbg_reseed(dctx, adin, adinlen, hcheck)) {
+            r = FIPS_R_RESEED_ERROR;
+            goto end;
+        }
+        adin = NULL;
+        adinlen = 0;
+    }
+
+    if (!dctx->generate(dctx, out, outlen, adin, adinlen)) {
+        r = FIPS_R_GENERATE_ERROR;
+        dctx->status = DRBG_STATUS_ERROR;
+        goto end;
+    }
+    if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) {
+        if (dctx->reseed_counter >= dctx->reseed_interval)
+            dctx->status = DRBG_STATUS_RESEED;
+        else
+            dctx->reseed_counter++;
+    }
+
+ end:
+    if (r) {
+        if (!(dctx->iflags & DRBG_FLAG_NOERR))
+            FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r);
+        return 0;
+    }
+
+    return 1;
+}
+
+int FIPS_drbg_uninstantiate(DRBG_CTX *dctx)
+{
+    int rv;
+    if (!dctx->uninstantiate)
+        rv = 1;
+    else
+        rv = dctx->uninstantiate(dctx);
+    /* Although we'd like to cleanse here we can't because we have to
+     * test the uninstantiate really zeroes the data.
+     */
+    memset(&dctx->d, 0, sizeof(dctx->d));
+    dctx->status = DRBG_STATUS_UNINITIALISED;
+    /* If method has problems uninstantiating, return error */
+    return rv;
+}
+
+int FIPS_drbg_set_callbacks(DRBG_CTX *dctx,
+                            size_t (*get_entropy) (DRBG_CTX *ctx,
+                                                   unsigned char **pout,
+                                                   int entropy,
+                                                   size_t min_len,
+                                                   size_t max_len),
+                            void (*cleanup_entropy) (DRBG_CTX *ctx,
+                                                     unsigned char *out,
+                                                     size_t olen),
+                            size_t entropy_blocklen,
+                            size_t (*get_nonce) (DRBG_CTX *ctx,
+                                                 unsigned char **pout,
+                                                 int entropy, size_t min_len,
+                                                 size_t max_len),
+                            void (*cleanup_nonce) (DRBG_CTX *ctx,
+                                                   unsigned char *out,
+                                                   size_t olen))
+{
+    if (dctx->status != DRBG_STATUS_UNINITIALISED)
+        return 0;
+    dctx->entropy_blocklen = entropy_blocklen;
+    dctx->get_entropy = get_entropy;
+    dctx->cleanup_entropy = cleanup_entropy;
+    dctx->get_nonce = get_nonce;
+    dctx->cleanup_nonce = cleanup_nonce;
+    return 1;
+}
+
+int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx,
+                                 size_t (*get_adin) (DRBG_CTX *ctx,
+                                                     unsigned char **pout),
+                                 void (*cleanup_adin) (DRBG_CTX *ctx,
+                                                       unsigned char *out,
+                                                       size_t olen),
+                                 int (*rand_seed_cb) (DRBG_CTX *ctx,
+                                                      const void *buf,
+                                                      int num),
+                                 int (*rand_add_cb) (DRBG_CTX *ctx,
+                                                     const void *buf, int num,
+                                                     double entropy))
+{
+    if (dctx->status != DRBG_STATUS_UNINITIALISED)
+        return 0;
+    dctx->get_adin = get_adin;
+    dctx->cleanup_adin = cleanup_adin;
+    dctx->rand_seed_cb = rand_seed_cb;
+    dctx->rand_add_cb = rand_add_cb;
+    return 1;
+}
+
+void *FIPS_drbg_get_app_data(DRBG_CTX *dctx)
+{
+    return dctx->app_data;
+}
+
+void FIPS_drbg_set_app_data(DRBG_CTX *dctx, void *app_data)
+{
+    dctx->app_data = app_data;
+}
+
+size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx)
+{
+    return dctx->blocklength;
+}
+
+int FIPS_drbg_get_strength(DRBG_CTX *dctx)
+{
+    return dctx->strength;
+}
+
+void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval)
+{
+    dctx->health_check_interval = interval;
+}
+
+void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval)
+{
+    dctx->reseed_interval = interval;
+}
+
+static int drbg_stick = 0;
+
+void FIPS_drbg_stick(int onoff)
+{
+    drbg_stick = onoff;
+}
+
+/* Continuous DRBG utility function */
+int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out)
+{
+    /* No CPRNG in test mode */
+    if (dctx->xflags & DRBG_FLAG_TEST)
+        return 1;
+    /* Check block is valid: should never happen */
+    if (dctx->lb_valid == 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_CPRNG_TEST, FIPS_R_INTERNAL_ERROR);
+        fips_set_selftest_fail();
+        return 0;
+    }
+    if (drbg_stick)
+        memcpy(dctx->lb, out, dctx->blocklength);
+    /* Check against last block: fail if match */
+    if (!memcmp(dctx->lb, out, dctx->blocklength)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_CPRNG_TEST, FIPS_R_DRBG_STUCK);
+        fips_set_selftest_fail();
+        return 0;
+    }
+    /* Save last block for next comparison */
+    memcpy(dctx->lb, out, dctx->blocklength);
+    return 1;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_drbg_rand.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_rand.c
--- openssl-1.0.2i/crypto/fips/fips_drbg_rand.c.fips	2016-09-22 13:35:57.015220951 +0200
+++ openssl-1.0.2i/crypto/fips/fips_drbg_rand.c	2016-09-22 13:35:57.015220951 +0200
@@ -0,0 +1,164 @@
+/* fips/rand/fips_drbg_rand.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include "fips_rand_lcl.h"
+
+/* Mapping of SP800-90 DRBGs to OpenSSL RAND_METHOD */
+
+/* Since we only have one global PRNG used at any time in OpenSSL use a global
+ * variable to store context.
+ */
+
+static DRBG_CTX ossl_dctx;
+
+DRBG_CTX *FIPS_get_default_drbg(void)
+{
+    return &ossl_dctx;
+}
+
+static int fips_drbg_bytes(unsigned char *out, int count)
+{
+    DRBG_CTX *dctx = &ossl_dctx;
+    int rv = 0;
+    unsigned char *adin = NULL;
+    size_t adinlen = 0;
+    CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+    do {
+        size_t rcnt;
+        if (count > (int)dctx->max_request)
+            rcnt = dctx->max_request;
+        else
+            rcnt = count;
+        if (dctx->get_adin) {
+            adinlen = dctx->get_adin(dctx, &adin);
+            if (adinlen && !adin) {
+                FIPSerr(FIPS_F_FIPS_DRBG_BYTES,
+                        FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT);
+                goto err;
+            }
+        }
+        rv = FIPS_drbg_generate(dctx, out, rcnt, 0, adin, adinlen);
+        if (adin) {
+            if (dctx->cleanup_adin)
+                dctx->cleanup_adin(dctx, adin, adinlen);
+            adin = NULL;
+        }
+        if (!rv)
+            goto err;
+        out += rcnt;
+        count -= rcnt;
+    }
+    while (count);
+    rv = 1;
+ err:
+    CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+    return rv;
+}
+
+static int fips_drbg_pseudo(unsigned char *out, int count)
+{
+    if (fips_drbg_bytes(out, count) <= 0)
+        return -1;
+    return 1;
+}
+
+static int fips_drbg_status(void)
+{
+    DRBG_CTX *dctx = &ossl_dctx;
+    int rv;
+    rv = dctx->status == DRBG_STATUS_READY ? 1 : 0;
+    return rv;
+}
+
+static void fips_drbg_cleanup(void)
+{
+    DRBG_CTX *dctx = &ossl_dctx;
+    CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+    FIPS_drbg_uninstantiate(dctx);
+    CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+}
+
+static int fips_drbg_seed(const void *seed, int seedlen)
+{
+    DRBG_CTX *dctx = &ossl_dctx;
+    if (dctx->rand_seed_cb)
+        return dctx->rand_seed_cb(dctx, seed, seedlen);
+    return 1;
+}
+
+static int fips_drbg_add(const void *seed, int seedlen, double add_entropy)
+{
+    DRBG_CTX *dctx = &ossl_dctx;
+    if (dctx->rand_add_cb)
+        return dctx->rand_add_cb(dctx, seed, seedlen, add_entropy);
+    return 1;
+}
+
+static const RAND_METHOD rand_drbg_meth = {
+    fips_drbg_seed,
+    fips_drbg_bytes,
+    fips_drbg_cleanup,
+    fips_drbg_add,
+    fips_drbg_pseudo,
+    fips_drbg_status
+};
+
+const RAND_METHOD *FIPS_drbg_method(void)
+{
+    return &rand_drbg_meth;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c.fips	2016-09-22 13:35:57.015220951 +0200
+++ openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c	2016-09-22 13:35:57.015220951 +0200
@@ -0,0 +1,827 @@
+/* fips/rand/fips_drbg_selftest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/fips_rand.h>
+#include "fips_rand_lcl.h"
+#include "fips_locl.h"
+
+#include "fips_drbg_selftest.h"
+
+typedef struct {
+    int post;
+    int nid;
+    unsigned int flags;
+
+    /* KAT data for no PR */
+    const unsigned char *ent;
+    size_t entlen;
+    const unsigned char *nonce;
+    size_t noncelen;
+    const unsigned char *pers;
+    size_t perslen;
+    const unsigned char *adin;
+    size_t adinlen;
+    const unsigned char *entreseed;
+    size_t entreseedlen;
+    const unsigned char *adinreseed;
+    size_t adinreseedlen;
+    const unsigned char *adin2;
+    size_t adin2len;
+    const unsigned char *kat;
+    size_t katlen;
+    const unsigned char *kat2;
+    size_t kat2len;
+
+    /* KAT data for PR */
+    const unsigned char *ent_pr;
+    size_t entlen_pr;
+    const unsigned char *nonce_pr;
+    size_t noncelen_pr;
+    const unsigned char *pers_pr;
+    size_t perslen_pr;
+    const unsigned char *adin_pr;
+    size_t adinlen_pr;
+    const unsigned char *entpr_pr;
+    size_t entprlen_pr;
+    const unsigned char *ading_pr;
+    size_t adinglen_pr;
+    const unsigned char *entg_pr;
+    size_t entglen_pr;
+    const unsigned char *kat_pr;
+    size_t katlen_pr;
+    const unsigned char *kat2_pr;
+    size_t kat2len_pr;
+
+} DRBG_SELFTEST_DATA;
+
+#define make_drbg_test_data(nid, flag, pr, p) {p, nid, flag | DRBG_FLAG_TEST, \
+        pr##_entropyinput, sizeof(pr##_entropyinput), \
+        pr##_nonce, sizeof(pr##_nonce), \
+        pr##_personalizationstring, sizeof(pr##_personalizationstring), \
+        pr##_additionalinput, sizeof(pr##_additionalinput), \
+        pr##_entropyinputreseed, sizeof(pr##_entropyinputreseed), \
+        pr##_additionalinputreseed, sizeof(pr##_additionalinputreseed), \
+        pr##_additionalinput2, sizeof(pr##_additionalinput2), \
+        pr##_int_returnedbits, sizeof(pr##_int_returnedbits), \
+        pr##_returnedbits, sizeof(pr##_returnedbits), \
+        pr##_pr_entropyinput, sizeof(pr##_pr_entropyinput), \
+        pr##_pr_nonce, sizeof(pr##_pr_nonce), \
+        pr##_pr_personalizationstring, sizeof(pr##_pr_personalizationstring), \
+        pr##_pr_additionalinput, sizeof(pr##_pr_additionalinput), \
+        pr##_pr_entropyinputpr, sizeof(pr##_pr_entropyinputpr), \
+        pr##_pr_additionalinput2, sizeof(pr##_pr_additionalinput2), \
+        pr##_pr_entropyinputpr2, sizeof(pr##_pr_entropyinputpr2), \
+        pr##_pr_int_returnedbits, sizeof(pr##_pr_int_returnedbits), \
+        pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits), \
+        }
+
+#define make_drbg_test_data_df(nid, pr, p) \
+        make_drbg_test_data(nid, DRBG_FLAG_CTR_USE_DF, pr, p)
+
+#define make_drbg_test_data_ec(curve, md, pr, p) \
+        make_drbg_test_data((curve << 16) | md , 0, pr, p)
+
+static DRBG_SELFTEST_DATA drbg_test[] = {
+    make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0),
+    make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0),
+    make_drbg_test_data_df(NID_aes_256_ctr, aes_256_use_df, 1),
+    make_drbg_test_data(NID_aes_128_ctr, 0, aes_128_no_df, 0),
+    make_drbg_test_data(NID_aes_192_ctr, 0, aes_192_no_df, 0),
+    make_drbg_test_data(NID_aes_256_ctr, 0, aes_256_no_df, 1),
+    make_drbg_test_data(NID_sha1, 0, sha1, 0),
+    make_drbg_test_data(NID_sha224, 0, sha224, 0),
+    make_drbg_test_data(NID_sha256, 0, sha256, 1),
+    make_drbg_test_data(NID_sha384, 0, sha384, 0),
+    make_drbg_test_data(NID_sha512, 0, sha512, 0),
+    make_drbg_test_data(NID_hmacWithSHA1, 0, hmac_sha1, 0),
+    make_drbg_test_data(NID_hmacWithSHA224, 0, hmac_sha224, 0),
+    make_drbg_test_data(NID_hmacWithSHA256, 0, hmac_sha256, 1),
+    make_drbg_test_data(NID_hmacWithSHA384, 0, hmac_sha384, 0),
+    make_drbg_test_data(NID_hmacWithSHA512, 0, hmac_sha512, 0),
+    {0, 0, 0}
+};
+
+typedef struct {
+    const unsigned char *ent;
+    size_t entlen;
+    int entcnt;
+    const unsigned char *nonce;
+    size_t noncelen;
+    int noncecnt;
+} TEST_ENT;
+
+static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout,
+                           int entropy, size_t min_len, size_t max_len)
+{
+    TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
+    *pout = (unsigned char *)t->ent;
+    t->entcnt++;
+    return t->entlen;
+}
+
+static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout,
+                         int entropy, size_t min_len, size_t max_len)
+{
+    TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
+    *pout = (unsigned char *)t->nonce;
+    t->noncecnt++;
+    return t->noncelen;
+}
+
+static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td,
+                                int quick)
+{
+    TEST_ENT t;
+    int rv = 0;
+    size_t adinlen;
+    unsigned char randout[1024];
+
+    /* Initial test without PR */
+
+    /* Instantiate DRBG with test entropy, nonce and personalisation
+     * string.
+     */
+
+    if (!FIPS_drbg_init(dctx, td->nid, td->flags))
+        return 0;
+    if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
+        return 0;
+
+    FIPS_drbg_set_app_data(dctx, &t);
+
+    t.ent = td->ent;
+    t.entlen = td->entlen;
+    t.nonce = td->nonce;
+    t.noncelen = td->noncelen;
+    t.entcnt = 0;
+    t.noncecnt = 0;
+
+    if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen))
+        goto err;
+
+    /* Note for CTR without DF some additional input values
+     * ignore bytes after the keylength: so reduce adinlen
+     * to half to ensure invalid data is fed in.
+     */
+    if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags))
+        adinlen = td->adinlen / 2;
+    else
+        adinlen = td->adinlen;
+
+    /* Generate with no PR and verify output matches expected data */
+    if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, td->adin, adinlen))
+        goto err;
+
+    if (memcmp(randout, td->kat, td->katlen)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST1_FAILURE);
+        goto err2;
+    }
+    /* If abbreviated POST end of test */
+    if (quick) {
+        rv = 1;
+        goto err;
+    }
+    /* Reseed DRBG with test entropy and additional input */
+    t.ent = td->entreseed;
+    t.entlen = td->entreseedlen;
+
+    if (!FIPS_drbg_reseed(dctx, td->adinreseed, td->adinreseedlen))
+        goto err;
+
+    /* Generate with no PR and verify output matches expected data */
+    if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0,
+                            td->adin2, td->adin2len))
+        goto err;
+
+    if (memcmp(randout, td->kat2, td->kat2len)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST2_FAILURE);
+        goto err2;
+    }
+
+    FIPS_drbg_uninstantiate(dctx);
+
+    /* Now test with PR */
+
+    /* Instantiate DRBG with test entropy, nonce and personalisation
+     * string.
+     */
+    if (!FIPS_drbg_init(dctx, td->nid, td->flags))
+        return 0;
+    if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
+        return 0;
+
+    FIPS_drbg_set_app_data(dctx, &t);
+
+    t.ent = td->ent_pr;
+    t.entlen = td->entlen_pr;
+    t.nonce = td->nonce_pr;
+    t.noncelen = td->noncelen_pr;
+    t.entcnt = 0;
+    t.noncecnt = 0;
+
+    if (!FIPS_drbg_instantiate(dctx, td->pers_pr, td->perslen_pr))
+        goto err;
+
+    /* Now generate with PR: we need to supply entropy as this will
+     * perform a reseed operation. Check output matches expected value.
+     */
+
+    t.ent = td->entpr_pr;
+    t.entlen = td->entprlen_pr;
+
+    /* Note for CTR without DF some additional input values
+     * ignore bytes after the keylength: so reduce adinlen
+     * to half to ensure invalid data is fed in.
+     */
+    if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags))
+        adinlen = td->adinlen_pr / 2;
+    else
+        adinlen = td->adinlen_pr;
+    if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 1,
+                            td->adin_pr, adinlen))
+        goto err;
+
+    if (memcmp(randout, td->kat_pr, td->katlen_pr)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST1_FAILURE);
+        goto err2;
+    }
+
+    /* Now generate again with PR: supply new entropy again.
+     * Check output matches expected value.
+     */
+
+    t.ent = td->entg_pr;
+    t.entlen = td->entglen_pr;
+
+    if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 1,
+                            td->ading_pr, td->adinglen_pr))
+        goto err;
+
+    if (memcmp(randout, td->kat2_pr, td->kat2len_pr)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST2_FAILURE);
+        goto err2;
+    }
+    /* All OK, test complete */
+    rv = 1;
+
+ err:
+    if (rv == 0)
+        FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_SELFTEST_FAILED);
+ err2:
+    FIPS_drbg_uninstantiate(dctx);
+
+    return rv;
+
+}
+
+/* Initialise a DRBG based on selftest data */
+
+static int do_drbg_init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td, TEST_ENT * t)
+{
+
+    if (!FIPS_drbg_init(dctx, td->nid, td->flags))
+        return 0;
+
+    if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0))
+        return 0;
+
+    FIPS_drbg_set_app_data(dctx, t);
+
+    t->ent = td->ent;
+    t->entlen = td->entlen;
+    t->nonce = td->nonce;
+    t->noncelen = td->noncelen;
+    t->entcnt = 0;
+    t->noncecnt = 0;
+    return 1;
+}
+
+/* Initialise and instantiate DRBG based on selftest data */
+static int do_drbg_instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td,
+                               TEST_ENT * t)
+{
+    if (!do_drbg_init(dctx, td, t))
+        return 0;
+    if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen))
+        return 0;
+
+    return 1;
+}
+
+/* This function performs extensive error checking as required by SP800-90.
+ * Induce several failure modes and check an error condition is set.
+ * This function along with fips_drbg_single_kat peforms the health checking
+ * operation.
+ */
+
+static int fips_drbg_error_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td)
+{
+    unsigned char randout[1024];
+    TEST_ENT t;
+    size_t i;
+    unsigned int reseed_counter_tmp;
+    unsigned char *p = (unsigned char *)dctx;
+
+    /* Initialise DRBG */
+
+    if (!do_drbg_init(dctx, td, &t))
+        goto err;
+
+    /* Don't report induced errors */
+    dctx->iflags |= DRBG_FLAG_NOERR;
+
+    /* Personalisation string tests */
+
+    /* Test detection of too large personlisation string */
+
+    if (FIPS_drbg_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_PERSONALISATION_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    /* Entropy source tests */
+
+    /* Test entropy source failure detecion: i.e. returns no data */
+
+    t.entlen = 0;
+
+    if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    /* Try to generate output from uninstantiated DRBG */
+    if (FIPS_drbg_generate(dctx, randout, td->katlen, 0,
+                           td->adin, td->adinlen)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_GENERATE_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    dctx->iflags &= ~DRBG_FLAG_NOERR;
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    if (!do_drbg_init(dctx, td, &t))
+        goto err;
+
+    dctx->iflags |= DRBG_FLAG_NOERR;
+
+    /* Test insufficient entropy */
+
+    t.entlen = dctx->min_entropy - 1;
+
+    if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    dctx->iflags &= ~DRBG_FLAG_NOERR;
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    /* Test too much entropy */
+
+    if (!do_drbg_init(dctx, td, &t))
+        goto err;
+
+    dctx->iflags |= DRBG_FLAG_NOERR;
+
+    t.entlen = dctx->max_entropy + 1;
+
+    if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    dctx->iflags &= ~DRBG_FLAG_NOERR;
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    /* Nonce tests */
+
+    /* Test too small nonce */
+
+    if (dctx->min_nonce) {
+
+        if (!do_drbg_init(dctx, td, &t))
+            goto err;
+
+        dctx->iflags |= DRBG_FLAG_NOERR;
+
+        t.noncelen = dctx->min_nonce - 1;
+
+        if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) {
+            FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                    FIPS_R_NONCE_ERROR_UNDETECTED);
+            goto err;
+        }
+
+        dctx->iflags &= ~DRBG_FLAG_NOERR;
+        if (!FIPS_drbg_uninstantiate(dctx)) {
+            FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+            goto err;
+        }
+
+    }
+
+    /* Test too large nonce */
+
+    if (dctx->max_nonce) {
+
+        if (!do_drbg_init(dctx, td, &t))
+            goto err;
+
+        dctx->iflags |= DRBG_FLAG_NOERR;
+
+        t.noncelen = dctx->max_nonce + 1;
+
+        if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) {
+            FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                    FIPS_R_NONCE_ERROR_UNDETECTED);
+            goto err;
+        }
+
+        dctx->iflags &= ~DRBG_FLAG_NOERR;
+        if (!FIPS_drbg_uninstantiate(dctx)) {
+            FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+            goto err;
+        }
+
+    }
+
+    /* Instantiate with valid data. */
+    if (!do_drbg_instantiate(dctx, td, &t))
+        goto err;
+
+    /* Check generation is now OK */
+    if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
+                            td->adin, td->adinlen))
+        goto err;
+
+    dctx->iflags |= DRBG_FLAG_NOERR;
+
+    /* Request too much data for one request */
+    if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0,
+                           td->adin, td->adinlen)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    /* Try too large additional input */
+    if (FIPS_drbg_generate(dctx, randout, td->katlen, 0,
+                           td->adin, dctx->max_adin + 1)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    /* Check prediction resistance request fails if entropy source
+     * failure.
+     */
+
+    t.entlen = 0;
+
+    if (FIPS_drbg_generate(dctx, randout, td->katlen, 1,
+                           td->adin, td->adinlen)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    dctx->iflags &= ~DRBG_FLAG_NOERR;
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    /* Instantiate again with valid data */
+
+    if (!do_drbg_instantiate(dctx, td, &t))
+        goto err;
+    /* Test reseed counter works */
+    /* Save initial reseed counter */
+    reseed_counter_tmp = dctx->reseed_counter;
+    /* Set reseed counter to beyond interval */
+    dctx->reseed_counter = dctx->reseed_interval;
+
+    /* Generate output and check entropy has been requested for reseed */
+    t.entcnt = 0;
+    if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
+                            td->adin, td->adinlen))
+        goto err;
+    if (t.entcnt != 1) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED);
+        goto err;
+    }
+    /* Check reseed counter has been reset */
+    if (dctx->reseed_counter != reseed_counter_tmp + 1) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR);
+        goto err;
+    }
+
+    dctx->iflags &= ~DRBG_FLAG_NOERR;
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    /* Check prediction resistance request fails if entropy source
+     * failure.
+     */
+
+    t.entlen = 0;
+
+    dctx->iflags |= DRBG_FLAG_NOERR;
+    if (FIPS_drbg_generate(dctx, randout, td->katlen, 1,
+                           td->adin, td->adinlen)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    dctx->iflags &= ~DRBG_FLAG_NOERR;
+
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    if (!do_drbg_instantiate(dctx, td, &t))
+        goto err;
+    /* Test reseed counter works */
+    /* Save initial reseed counter */
+    reseed_counter_tmp = dctx->reseed_counter;
+    /* Set reseed counter to beyond interval */
+    dctx->reseed_counter = dctx->reseed_interval;
+
+    /* Generate output and check entropy has been requested for reseed */
+    t.entcnt = 0;
+    if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0,
+                            td->adin, td->adinlen))
+        goto err;
+    if (t.entcnt != 1) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED);
+        goto err;
+    }
+    /* Check reseed counter has been reset */
+    if (dctx->reseed_counter != reseed_counter_tmp + 1) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR);
+        goto err;
+    }
+
+    dctx->iflags &= ~DRBG_FLAG_NOERR;
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    /* Explicit reseed tests */
+
+    /* Test explicit reseed with too large additional input */
+    if (!do_drbg_init(dctx, td, &t))
+        goto err;
+
+    dctx->iflags |= DRBG_FLAG_NOERR;
+
+    if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    /* Test explicit reseed with entropy source failure */
+
+    t.entlen = 0;
+
+    if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    /* Test explicit reseed with too much entropy */
+
+    if (!do_drbg_init(dctx, td, &t))
+        goto err;
+
+    dctx->iflags |= DRBG_FLAG_NOERR;
+
+    t.entlen = dctx->max_entropy + 1;
+
+    if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    /* Test explicit reseed with too little entropy */
+
+    if (!do_drbg_init(dctx, td, &t))
+        goto err;
+
+    dctx->iflags |= DRBG_FLAG_NOERR;
+
+    t.entlen = dctx->min_entropy - 1;
+
+    if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                FIPS_R_ENTROPY_ERROR_UNDETECTED);
+        goto err;
+    }
+
+    if (!FIPS_drbg_uninstantiate(dctx)) {
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR);
+        goto err;
+    }
+
+    p = (unsigned char *)&dctx->d;
+    /* Standard says we have to check uninstantiate really zeroes
+     * the data...
+     */
+    for (i = 0; i < sizeof(dctx->d); i++) {
+        if (*p != 0) {
+            FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK,
+                    FIPS_R_UNINSTANTIATE_ZEROISE_ERROR);
+            goto err;
+        }
+        p++;
+    }
+
+    return 1;
+
+ err:
+    /* A real error as opposed to an induced one: underlying function will
+     * indicate the error.
+     */
+    if (!(dctx->iflags & DRBG_FLAG_NOERR))
+        FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_FUNCTION_ERROR);
+    FIPS_drbg_uninstantiate(dctx);
+    return 0;
+
+}
+
+int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags)
+{
+    DRBG_SELFTEST_DATA *td;
+    flags |= DRBG_FLAG_TEST;
+    for (td = drbg_test; td->nid != 0; td++) {
+        if (td->nid == nid && td->flags == flags) {
+            if (!fips_drbg_single_kat(dctx, td, 0))
+                return 0;
+            return fips_drbg_error_check(dctx, td);
+        }
+    }
+    return 0;
+}
+
+int FIPS_drbg_health_check(DRBG_CTX *dctx)
+{
+    int rv;
+    DRBG_CTX *tctx = NULL;
+    tctx = FIPS_drbg_new(0, 0);
+    fips_post_started(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
+    if (!tctx)
+        return 0;
+    rv = fips_drbg_kat(tctx, dctx->type, dctx->xflags);
+    if (tctx)
+        FIPS_drbg_free(tctx);
+    if (rv)
+        fips_post_success(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
+    else
+        fips_post_failed(FIPS_TEST_DRBG, dctx->type, &dctx->xflags);
+    if (!rv)
+        dctx->status = DRBG_STATUS_ERROR;
+    else
+        dctx->health_check_cnt = 0;
+    return rv;
+}
+
+int FIPS_selftest_drbg(void)
+{
+    DRBG_CTX *dctx;
+    DRBG_SELFTEST_DATA *td;
+    int rv = 1;
+    dctx = FIPS_drbg_new(0, 0);
+    if (!dctx)
+        return 0;
+    for (td = drbg_test; td->nid != 0; td++) {
+        if (td->post != 1)
+            continue;
+        if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags))
+            return 1;
+        if (!fips_drbg_single_kat(dctx, td, 1)) {
+            fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
+            rv = 0;
+            continue;
+        }
+        if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags))
+            return 0;
+    }
+    FIPS_drbg_free(dctx);
+    return rv;
+}
+
+int FIPS_selftest_drbg_all(void)
+{
+    DRBG_CTX *dctx;
+    DRBG_SELFTEST_DATA *td;
+    int rv = 1;
+    dctx = FIPS_drbg_new(0, 0);
+    if (!dctx)
+        return 0;
+    for (td = drbg_test; td->nid != 0; td++) {
+        if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags))
+            return 1;
+        if (!fips_drbg_single_kat(dctx, td, 0)) {
+            fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
+            rv = 0;
+            continue;
+        }
+        if (!fips_drbg_error_check(dctx, td)) {
+            fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags);
+            rv = 0;
+            continue;
+        }
+        if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags))
+            return 0;
+    }
+    FIPS_drbg_free(dctx);
+    return rv;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h.fips openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h
--- openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h.fips	2016-09-22 13:35:57.016220974 +0200
+++ openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h	2016-09-22 13:35:57.016220974 +0200
@@ -0,0 +1,1791 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* Selftest and health check data for the SP800-90 DRBG */
+
+#define __fips_constseg
+
+/* AES-128 use df PR  */
+__fips_constseg static const unsigned char aes_128_use_df_pr_entropyinput[] = {
+    0x61, 0x52, 0x7c, 0xe3, 0x23, 0x7d, 0x0a, 0x07, 0x10, 0x0c, 0x50, 0x33,
+    0xc8, 0xdb, 0xff, 0x12
+};
+
+__fips_constseg static const unsigned char aes_128_use_df_pr_nonce[] = {
+    0x51, 0x0d, 0x85, 0x77, 0xed, 0x22, 0x97, 0x28
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_pr_personalizationstring[] = {
+    0x59, 0x9f, 0xbb, 0xcd, 0xd5, 0x25, 0x69, 0xb5, 0xcb, 0xb5, 0x03, 0xfe,
+    0xd7, 0xd7, 0x01, 0x67
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_pr_additionalinput[] = {
+    0xef, 0x88, 0x76, 0x01, 0xaf, 0x3c, 0xfe, 0x8b, 0xaf, 0x26, 0x06, 0x9e,
+    0x9a, 0x47, 0x08, 0x76
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_pr_entropyinputpr[] = {
+    0xe2, 0x76, 0xf9, 0xf6, 0x3a, 0xba, 0x10, 0x9f, 0xbf, 0x47, 0x0e, 0x51,
+    0x09, 0xfb, 0xa3, 0xb6
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_pr_int_returnedbits[] = {
+    0xd4, 0x98, 0x8a, 0x46, 0x80, 0x4c, 0xdb, 0xa3, 0x59, 0x02, 0x57, 0x52,
+    0x66, 0x1c, 0xea, 0x5b
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_pr_additionalinput2[] = {
+    0x88, 0x8c, 0x91, 0xd6, 0xbe, 0x56, 0x6e, 0x08, 0x9a, 0x62, 0x2b, 0x11,
+    0x3f, 0x5e, 0x31, 0x06
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_pr_entropyinputpr2[] = {
+    0xc0, 0x5c, 0x6b, 0x98, 0x01, 0x0d, 0x58, 0x18, 0x51, 0x18, 0x96, 0xae,
+    0xa7, 0xe3, 0xa8, 0x67
+};
+
+__fips_constseg static const unsigned char aes_128_use_df_pr_returnedbits[] = {
+    0xcf, 0x01, 0xac, 0x22, 0x31, 0x06, 0x8e, 0xfc, 0xce, 0x56, 0xea, 0x24,
+    0x0f, 0x38, 0x43, 0xc6
+};
+
+/* AES-128 use df No PR  */
+__fips_constseg static const unsigned char aes_128_use_df_entropyinput[] = {
+    0x1f, 0x8e, 0x34, 0x82, 0x0c, 0xb7, 0xbe, 0xc5, 0x01, 0x3e, 0xd0, 0xa3,
+    0x9d, 0x7d, 0x1c, 0x9b
+};
+
+__fips_constseg static const unsigned char aes_128_use_df_nonce[] = {
+    0xd5, 0x4d, 0xbd, 0x4a, 0x93, 0x7f, 0xb8, 0x96
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_personalizationstring[] = {
+    0xab, 0xd6, 0x3f, 0x04, 0xfe, 0x27, 0x6b, 0x2d, 0xd7, 0xc3, 0x1c, 0xf3,
+    0x38, 0x66, 0xba, 0x1b
+};
+
+__fips_constseg static const unsigned char aes_128_use_df_additionalinput[] = {
+    0xfe, 0xf4, 0x09, 0xa8, 0xb7, 0x73, 0x27, 0x9c, 0x5f, 0xa7, 0xea, 0x46,
+    0xb5, 0xe2, 0xb2, 0x41
+};
+
+__fips_constseg static const unsigned char aes_128_use_df_int_returnedbits[] = {
+    0x42, 0xe4, 0x4e, 0x7b, 0x27, 0xdd, 0xcb, 0xbc, 0x0a, 0xcf, 0xa6, 0x67,
+    0xe7, 0x57, 0x11, 0xb4
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_entropyinputreseed[] = {
+    0x14, 0x26, 0x69, 0xd9, 0xf3, 0x65, 0x03, 0xd6, 0x6b, 0xb9, 0x44, 0x0b,
+    0xc7, 0xc4, 0x9e, 0x39
+};
+
+__fips_constseg
+    static const unsigned char aes_128_use_df_additionalinputreseed[] = {
+    0x55, 0x2e, 0x60, 0x9a, 0x05, 0x72, 0x8a, 0xa8, 0xef, 0x22, 0x81, 0x5a,
+    0xc8, 0x93, 0xfa, 0x84
+};
+
+__fips_constseg static const unsigned char aes_128_use_df_additionalinput2[] = {
+    0x3c, 0x40, 0xc8, 0xc4, 0x16, 0x0c, 0x21, 0xa4, 0x37, 0x2c, 0x8f, 0xa5,
+    0x06, 0x0c, 0x15, 0x2c
+};
+
+__fips_constseg static const unsigned char aes_128_use_df_returnedbits[] = {
+    0xe1, 0x3e, 0x99, 0x98, 0x86, 0x67, 0x0b, 0x63, 0x7b, 0xbe, 0x3f, 0x88,
+    0x46, 0x81, 0xc7, 0x19
+};
+
+/* AES-192 use df PR  */
+__fips_constseg static const unsigned char aes_192_use_df_pr_entropyinput[] = {
+    0x2b, 0x4e, 0x8b, 0xe1, 0xf1, 0x34, 0x80, 0x56, 0x81, 0xf9, 0x74, 0xec,
+    0x17, 0x44, 0x2a, 0xf1, 0x14, 0xb0, 0xbf, 0x97, 0x39, 0xb7, 0x04, 0x7d
+};
+
+__fips_constseg static const unsigned char aes_192_use_df_pr_nonce[] = {
+    0xd6, 0x9d, 0xeb, 0x14, 0x4e, 0x6c, 0x30, 0x1e, 0x39, 0x55, 0x73, 0xd0,
+    0xd1, 0x80, 0x78, 0xfa
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_pr_personalizationstring[] = {
+    0xfc, 0x43, 0x4a, 0xf8, 0x9a, 0x55, 0xb3, 0x53, 0x83, 0xe2, 0x18, 0x16,
+    0x0c, 0xdc, 0xcd, 0x5e, 0x4f, 0xa0, 0x03, 0x01, 0x2b, 0x9f, 0xe4, 0xd5,
+    0x7d, 0x49, 0xf0, 0x41, 0x9e, 0x3d, 0x99, 0x04
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_pr_additionalinput[] = {
+    0x5e, 0x9f, 0x49, 0x6f, 0x21, 0x8b, 0x1d, 0x32, 0xd5, 0x84, 0x5c, 0xac,
+    0xaf, 0xdf, 0xe4, 0x79, 0x9e, 0xaf, 0xa9, 0x82, 0xd0, 0xf8, 0x4f, 0xcb,
+    0x69, 0x10, 0x0a, 0x7e, 0x81, 0x57, 0xb5, 0x36
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_pr_entropyinputpr[] = {
+    0xd4, 0x81, 0x0c, 0xd7, 0x66, 0x39, 0xec, 0x42, 0x53, 0x87, 0x41, 0xa5,
+    0x1e, 0x7d, 0x80, 0x91, 0x8e, 0xbb, 0xed, 0xac, 0x14, 0x02, 0x1a, 0xd5
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_pr_int_returnedbits[] = {
+    0xdf, 0x1d, 0x39, 0x45, 0x7c, 0x9b, 0xc6, 0x2b, 0x7d, 0x8c, 0x93, 0xe9,
+    0x19, 0x30, 0x6b, 0x67
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_pr_additionalinput2[] = {
+    0x00, 0x71, 0x27, 0x4e, 0xd3, 0x14, 0xf1, 0x20, 0x7f, 0x4a, 0x41, 0x32,
+    0x2a, 0x97, 0x11, 0x43, 0x8f, 0x4a, 0x15, 0x7b, 0x9b, 0x51, 0x79, 0xda,
+    0x49, 0x3d, 0xde, 0xe8, 0xbc, 0x93, 0x91, 0x99
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_pr_entropyinputpr2[] = {
+    0x90, 0xee, 0x76, 0xa1, 0x45, 0x8d, 0xb7, 0x40, 0xb0, 0x11, 0xbf, 0xd0,
+    0x65, 0xd7, 0x3c, 0x7c, 0x4f, 0x20, 0x3f, 0x4e, 0x11, 0x9d, 0xb3, 0x5e
+};
+
+__fips_constseg static const unsigned char aes_192_use_df_pr_returnedbits[] = {
+    0x24, 0x3b, 0x20, 0xa4, 0x37, 0x66, 0xba, 0x72, 0x39, 0x3f, 0xcf, 0x3c,
+    0x7e, 0x1a, 0x2b, 0x83
+};
+
+/* AES-192 use df No PR  */
+__fips_constseg static const unsigned char aes_192_use_df_entropyinput[] = {
+    0x8d, 0x74, 0xa4, 0x50, 0x1a, 0x02, 0x68, 0x0c, 0x2a, 0x69, 0xc4, 0x82,
+    0x3b, 0xbb, 0xda, 0x0e, 0x7f, 0x77, 0xa3, 0x17, 0x78, 0x57, 0xb2, 0x7b
+};
+
+__fips_constseg static const unsigned char aes_192_use_df_nonce[] = {
+    0x75, 0xd5, 0x1f, 0xac, 0xa4, 0x8d, 0x42, 0x78, 0xd7, 0x69, 0x86, 0x9d,
+    0x77, 0xd7, 0x41, 0x0e
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_personalizationstring[] = {
+    0x4e, 0x33, 0x41, 0x3c, 0x9c, 0xc2, 0xd2, 0x53, 0xaf, 0x90, 0xea, 0xcf,
+    0x19, 0x50, 0x1e, 0xe6, 0x6f, 0x63, 0xc8, 0x32, 0x22, 0xdc, 0x07, 0x65,
+    0x9c, 0xd3, 0xf8, 0x30, 0x9e, 0xed, 0x35, 0x70
+};
+
+__fips_constseg static const unsigned char aes_192_use_df_additionalinput[] = {
+    0x5d, 0x8b, 0x8c, 0xc1, 0xdf, 0x0e, 0x02, 0x78, 0xfb, 0x19, 0xb8, 0x69,
+    0x78, 0x4e, 0x9c, 0x52, 0xbc, 0xc7, 0x20, 0xc9, 0xe6, 0x5e, 0x77, 0x22,
+    0x28, 0x3d, 0x0c, 0x9e, 0x68, 0xa8, 0x45, 0xd7
+};
+
+__fips_constseg static const unsigned char aes_192_use_df_int_returnedbits[] = {
+    0xd5, 0xe7, 0x08, 0xc5, 0x19, 0x99, 0xd5, 0x31, 0x03, 0x0a, 0x74, 0xb6,
+    0xb7, 0xed, 0xe9, 0xea
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_entropyinputreseed[] = {
+    0x9c, 0x26, 0xda, 0xf1, 0xac, 0xd9, 0x5a, 0xd6, 0xa8, 0x65, 0xf5, 0x02,
+    0x8f, 0xdc, 0xa2, 0x09, 0x54, 0xa6, 0xe2, 0xa4, 0xde, 0x32, 0xe0, 0x01
+};
+
+__fips_constseg
+    static const unsigned char aes_192_use_df_additionalinputreseed[] = {
+    0x9b, 0x90, 0xb0, 0x3a, 0x0e, 0x3a, 0x80, 0x07, 0x4a, 0xf4, 0xda, 0x76,
+    0x28, 0x30, 0x3c, 0xee, 0x54, 0x1b, 0x94, 0x59, 0x51, 0x43, 0x56, 0x77,
+    0xaf, 0x88, 0xdd, 0x63, 0x89, 0x47, 0x06, 0x65
+};
+
+__fips_constseg static const unsigned char aes_192_use_df_additionalinput2[] = {
+    0x3c, 0x11, 0x64, 0x7a, 0x96, 0xf5, 0xd8, 0xb8, 0xae, 0xd6, 0x70, 0x4e,
+    0x16, 0x96, 0xde, 0xe9, 0x62, 0xbc, 0xee, 0x28, 0x2f, 0x26, 0xa6, 0xf0,
+    0x56, 0xef, 0xa3, 0xf1, 0x6b, 0xa1, 0xb1, 0x77
+};
+
+__fips_constseg static const unsigned char aes_192_use_df_returnedbits[] = {
+    0x0b, 0xe2, 0x56, 0x03, 0x1e, 0xdb, 0x2c, 0x6d, 0x7f, 0x1b, 0x15, 0x58,
+    0x1a, 0xf9, 0x13, 0x28
+};
+
+/* AES-256 use df PR  */
+__fips_constseg static const unsigned char aes_256_use_df_pr_entropyinput[] = {
+    0x61, 0x68, 0xfc, 0x1a, 0xf0, 0xb5, 0x95, 0x6b, 0x85, 0x09, 0x9b, 0x74,
+    0x3f, 0x13, 0x78, 0x49, 0x3b, 0x85, 0xec, 0x93, 0x13, 0x3b, 0xa9, 0x4f,
+    0x96, 0xab, 0x2c, 0xe4, 0xc8, 0x8f, 0xdd, 0x6a
+};
+
+__fips_constseg static const unsigned char aes_256_use_df_pr_nonce[] = {
+    0xad, 0xd2, 0xbb, 0xba, 0xb7, 0x65, 0x89, 0xc3, 0x21, 0x6c, 0x55, 0x33,
+    0x2b, 0x36, 0xff, 0xa4
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_pr_personalizationstring[] = {
+    0x6e, 0xca, 0xe7, 0x20, 0x72, 0xd3, 0x84, 0x5a, 0x32, 0xd3, 0x4b, 0x24,
+    0x72, 0xc4, 0x63, 0x2b, 0x9d, 0x12, 0x24, 0x0c, 0x23, 0x26, 0x8e, 0x83,
+    0x16, 0x37, 0x0b, 0xd1, 0x06, 0x4f, 0x68, 0x6d
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_pr_additionalinput[] = {
+    0x7e, 0x08, 0x4a, 0xbb, 0xe3, 0x21, 0x7c, 0xc9, 0x23, 0xd2, 0xf8, 0xb0,
+    0x73, 0x98, 0xba, 0x84, 0x74, 0x23, 0xab, 0x06, 0x8a, 0xe2, 0x22, 0xd3,
+    0x7b, 0xce, 0x9b, 0xd2, 0x4a, 0x76, 0xb8, 0xde
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_pr_entropyinputpr[] = {
+    0x0b, 0x23, 0xaf, 0xdf, 0xf1, 0x62, 0xd7, 0xd3, 0x43, 0x97, 0xf8, 0x77,
+    0x04, 0xa8, 0x42, 0x20, 0xbd, 0xf6, 0x0f, 0xc1, 0x17, 0x2f, 0x9f, 0x54,
+    0xbb, 0x56, 0x17, 0x86, 0x68, 0x0e, 0xba, 0xa9
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_pr_int_returnedbits[] = {
+    0x31, 0x8e, 0xad, 0xaf, 0x40, 0xeb, 0x6b, 0x74, 0x31, 0x46, 0x80, 0xc7,
+    0x17, 0xab, 0x3c, 0x7a
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_pr_additionalinput2[] = {
+    0x94, 0x6b, 0xc9, 0x9f, 0xab, 0x8d, 0xc5, 0xec, 0x71, 0x88, 0x1d, 0x00,
+    0x8c, 0x89, 0x68, 0xe4, 0xc8, 0x07, 0x77, 0x36, 0x17, 0x6d, 0x79, 0x78,
+    0xc7, 0x06, 0x4e, 0x99, 0x04, 0x28, 0x29, 0xc3
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_pr_entropyinputpr2[] = {
+    0xbf, 0x6c, 0x59, 0x2a, 0x0d, 0x44, 0x0f, 0xae, 0x9a, 0x5e, 0x03, 0x73,
+    0xd8, 0xa6, 0xe1, 0xcf, 0x25, 0x61, 0x38, 0x24, 0x86, 0x9e, 0x53, 0xe8,
+    0xa4, 0xdf, 0x56, 0xf4, 0x06, 0x07, 0x9c, 0x0f
+};
+
+__fips_constseg static const unsigned char aes_256_use_df_pr_returnedbits[] = {
+    0x22, 0x4a, 0xb4, 0xb8, 0xb6, 0xee, 0x7d, 0xb1, 0x9e, 0xc9, 0xf9, 0xa0,
+    0xd9, 0xe2, 0x97, 0x00
+};
+
+/* AES-256 use df No PR  */
+__fips_constseg static const unsigned char aes_256_use_df_entropyinput[] = {
+    0xa5, 0x3e, 0x37, 0x10, 0x17, 0x43, 0x91, 0x93, 0x59, 0x1e, 0x47, 0x50,
+    0x87, 0xaa, 0xdd, 0xd5, 0xc1, 0xc3, 0x86, 0xcd, 0xca, 0x0d, 0xdb, 0x68,
+    0xe0, 0x02, 0xd8, 0x0f, 0xdc, 0x40, 0x1a, 0x47
+};
+
+__fips_constseg static const unsigned char aes_256_use_df_nonce[] = {
+    0xa9, 0x4d, 0xa5, 0x5a, 0xfd, 0xc5, 0x0c, 0xe5, 0x1c, 0x9a, 0x3b, 0x8a,
+    0x4c, 0x44, 0x84, 0x40
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_personalizationstring[] = {
+    0x8b, 0x52, 0xa2, 0x4a, 0x93, 0xc3, 0x4e, 0xa7, 0x1e, 0x1c, 0xa7, 0x05,
+    0xeb, 0x82, 0x9b, 0xa6, 0x5d, 0xe4, 0xd4, 0xe0, 0x7f, 0xa3, 0xd8, 0x6b,
+    0x37, 0x84, 0x5f, 0xf1, 0xc7, 0xd5, 0xf6, 0xd2
+};
+
+__fips_constseg static const unsigned char aes_256_use_df_additionalinput[] = {
+    0x20, 0xf4, 0x22, 0xed, 0xf8, 0x5c, 0xa1, 0x6a, 0x01, 0xcf, 0xbe, 0x5f,
+    0x8d, 0x6c, 0x94, 0x7f, 0xae, 0x12, 0xa8, 0x57, 0xdb, 0x2a, 0xa9, 0xbf,
+    0xc7, 0xb3, 0x65, 0x81, 0x80, 0x8d, 0x0d, 0x46
+};
+
+__fips_constseg static const unsigned char aes_256_use_df_int_returnedbits[] = {
+    0x4e, 0x44, 0xfd, 0xf3, 0x9e, 0x29, 0xa2, 0xb8, 0x0f, 0x5d, 0x6c, 0xe1,
+    0x28, 0x0c, 0x3b, 0xc1
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_entropyinputreseed[] = {
+    0xdd, 0x40, 0xe5, 0x98, 0x7b, 0x27, 0x16, 0x73, 0x15, 0x68, 0xd2, 0x76,
+    0xbf, 0x0c, 0x67, 0x15, 0x75, 0x79, 0x03, 0xd3, 0xde, 0xde, 0x91, 0x46,
+    0x42, 0xdd, 0xd4, 0x67, 0xc8, 0x79, 0xc8, 0x1e
+};
+
+__fips_constseg
+    static const unsigned char aes_256_use_df_additionalinputreseed[] = {
+    0x7f, 0xd8, 0x1f, 0xbd, 0x2a, 0xb5, 0x1c, 0x11, 0x5d, 0x83, 0x4e, 0x99,
+    0xf6, 0x5c, 0xa5, 0x40, 0x20, 0xed, 0x38, 0x8e, 0xd5, 0x9e, 0xe0, 0x75,
+    0x93, 0xfe, 0x12, 0x5e, 0x5d, 0x73, 0xfb, 0x75
+};
+
+__fips_constseg static const unsigned char aes_256_use_df_additionalinput2[] = {
+    0xcd, 0x2c, 0xff, 0x14, 0x69, 0x3e, 0x4c, 0x9e, 0xfd, 0xfe, 0x26, 0x0d,
+    0xe9, 0x86, 0x00, 0x49, 0x30, 0xba, 0xb1, 0xc6, 0x50, 0x57, 0x77, 0x2a,
+    0x62, 0x39, 0x2c, 0x3b, 0x74, 0xeb, 0xc9, 0x0d
+};
+
+__fips_constseg static const unsigned char aes_256_use_df_returnedbits[] = {
+    0x4f, 0x78, 0xbe, 0xb9, 0x4d, 0x97, 0x8c, 0xe9, 0xd0, 0x97, 0xfe, 0xad,
+    0xfa, 0xfd, 0x35, 0x5e
+};
+
+/* AES-128 no df PR  */
+__fips_constseg static const unsigned char aes_128_no_df_pr_entropyinput[] = {
+    0x9a, 0x25, 0x65, 0x10, 0x67, 0xd5, 0xb6, 0x6b, 0x70, 0xa1, 0xb3, 0xa4,
+    0x43, 0x95, 0x80, 0xc0, 0x84, 0x0a, 0x79, 0xb0, 0x88, 0x74, 0xf2, 0xbf,
+    0x31, 0x6c, 0x33, 0x38, 0x0b, 0x00, 0xb2, 0x5a
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_pr_nonce[] = {
+    0x78, 0x47, 0x6b, 0xf7, 0x90, 0x8e, 0x87, 0xf1
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_pr_personalizationstring[] = {
+    0xf7, 0x22, 0x1d, 0x3a, 0xbe, 0x1d, 0xca, 0x32, 0x1b, 0xbd, 0x87, 0x0c,
+    0x51, 0x24, 0x19, 0xee, 0xa3, 0x23, 0x09, 0x63, 0x33, 0x3d, 0xa8, 0x0c,
+    0x1c, 0xfa, 0x42, 0x89, 0xcc, 0x6f, 0xa0, 0xa8
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_pr_additionalinput[] = {
+    0xc9, 0xe0, 0x80, 0xbf, 0x8c, 0x45, 0x58, 0x39, 0xff, 0x00, 0xab, 0x02,
+    0x4c, 0x3e, 0x3a, 0x95, 0x9b, 0x80, 0xa8, 0x21, 0x2a, 0xee, 0xba, 0x73,
+    0xb1, 0xd9, 0xcf, 0x28, 0xf6, 0x8f, 0x9b, 0x12
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_pr_entropyinputpr[] = {
+    0x4c, 0xa8, 0xc5, 0xf0, 0x59, 0x9e, 0xa6, 0x8d, 0x26, 0x53, 0xd7, 0x8a,
+    0xa9, 0xd8, 0xf7, 0xed, 0xb2, 0xf9, 0x12, 0x42, 0xe1, 0xe5, 0xbd, 0xe7,
+    0xe7, 0x1d, 0x74, 0x99, 0x00, 0x9d, 0x31, 0x3e
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_pr_int_returnedbits[] = {
+    0xe2, 0xac, 0x20, 0xf0, 0x80, 0xe7, 0xbc, 0x7e, 0x9c, 0x7b, 0x65, 0x71,
+    0xaf, 0x19, 0x32, 0x16
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_pr_additionalinput2[] = {
+    0x32, 0x7f, 0x38, 0x8b, 0x73, 0x0a, 0x78, 0x83, 0xdc, 0x30, 0xbe, 0x9f,
+    0x10, 0x1f, 0xf5, 0x1f, 0xca, 0x00, 0xb5, 0x0d, 0xd6, 0x9d, 0x60, 0x83,
+    0x51, 0x54, 0x7d, 0x38, 0x23, 0x3a, 0x52, 0x50
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_pr_entropyinputpr2[] = {
+    0x18, 0x61, 0x53, 0x56, 0xed, 0xed, 0xd7, 0x20, 0xfb, 0x71, 0x04, 0x7a,
+    0xb2, 0xac, 0xc1, 0x28, 0xcd, 0xf2, 0xc2, 0xfc, 0xaa, 0xb1, 0x06, 0x07,
+    0xe9, 0x46, 0x95, 0x02, 0x48, 0x01, 0x78, 0xf9
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_pr_returnedbits[] = {
+    0x29, 0xc8, 0x1b, 0x15, 0xb1, 0xd1, 0xc2, 0xf6, 0x71, 0x86, 0x68, 0x33,
+    0x57, 0x82, 0x33, 0xaf
+};
+
+/* AES-128 no df No PR  */
+__fips_constseg static const unsigned char aes_128_no_df_entropyinput[] = {
+    0xc9, 0xc5, 0x79, 0xbc, 0xe8, 0xc5, 0x19, 0xd8, 0xbc, 0x66, 0x73, 0x67,
+    0xf6, 0xd3, 0x72, 0xaa, 0xa6, 0x16, 0xb8, 0x50, 0xb7, 0x47, 0x3a, 0x42,
+    0xab, 0xf4, 0x16, 0xb2, 0x96, 0xd2, 0xb6, 0x60
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_nonce[] = {
+    0x5f, 0xbf, 0x97, 0x0c, 0x4b, 0xa4, 0x87, 0x13
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_personalizationstring[] = {
+    0xce, 0xfb, 0x7b, 0x3f, 0xd4, 0x6b, 0x29, 0x0d, 0x69, 0x06, 0xff, 0xbb,
+    0xf2, 0xe5, 0xc6, 0x6c, 0x0a, 0x10, 0xa0, 0xcf, 0x1a, 0x48, 0xc7, 0x8b,
+    0x3c, 0x16, 0x88, 0xed, 0x50, 0x13, 0x81, 0xce
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_additionalinput[] = {
+    0x4b, 0x22, 0x46, 0x18, 0x02, 0x7b, 0xd2, 0x1b, 0x22, 0x42, 0x7c, 0x37,
+    0xd9, 0xf6, 0xe8, 0x9b, 0x12, 0x30, 0x5f, 0xe9, 0x90, 0xe8, 0x08, 0x24,
+    0x4f, 0x06, 0x66, 0xdb, 0x19, 0x2b, 0x13, 0x95
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_int_returnedbits[] = {
+    0x2e, 0x96, 0x70, 0x64, 0xfa, 0xdf, 0xdf, 0x57, 0xb5, 0x82, 0xee, 0xd6,
+    0xed, 0x3e, 0x65, 0xc2
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_entropyinputreseed[] = {
+    0x26, 0xc0, 0x72, 0x16, 0x3a, 0x4b, 0xb7, 0x99, 0xd4, 0x07, 0xaf, 0x66,
+    0x62, 0x36, 0x96, 0xa4, 0x51, 0x17, 0xfa, 0x07, 0x8b, 0x17, 0x5e, 0xa1,
+    0x2f, 0x3c, 0x10, 0xe7, 0x90, 0xd0, 0x46, 0x00
+};
+
+__fips_constseg
+    static const unsigned char aes_128_no_df_additionalinputreseed[] = {
+    0x83, 0x39, 0x37, 0x7b, 0x02, 0x06, 0xd2, 0x12, 0x13, 0x8d, 0x8b, 0xf2,
+    0xf0, 0xf6, 0x26, 0xeb, 0xa4, 0x22, 0x7b, 0xc2, 0xe7, 0xba, 0x79, 0xe4,
+    0x3b, 0x77, 0x5d, 0x4d, 0x47, 0xb2, 0x2d, 0xb4
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_additionalinput2[] = {
+    0x0b, 0xb9, 0x67, 0x37, 0xdb, 0x83, 0xdf, 0xca, 0x81, 0x8b, 0xf9, 0x3f,
+    0xf1, 0x11, 0x1b, 0x2f, 0xf0, 0x61, 0xa6, 0xdf, 0xba, 0xa3, 0xb1, 0xac,
+    0xd3, 0xe6, 0x09, 0xb8, 0x2c, 0x6a, 0x67, 0xd6
+};
+
+__fips_constseg static const unsigned char aes_128_no_df_returnedbits[] = {
+    0x1e, 0xa7, 0xa4, 0xe4, 0xe1, 0xa6, 0x7c, 0x69, 0x9a, 0x44, 0x6c, 0x36,
+    0x81, 0x37, 0x19, 0xd4
+};
+
+/* AES-192 no df PR  */
+__fips_constseg static const unsigned char aes_192_no_df_pr_entropyinput[] = {
+    0x9d, 0x2c, 0xd2, 0x55, 0x66, 0xea, 0xe0, 0xbe, 0x18, 0xb7, 0x76, 0xe7,
+    0x73, 0x35, 0xd8, 0x1f, 0xad, 0x3a, 0xe3, 0x81, 0x0e, 0x92, 0xd0, 0x61,
+    0xc9, 0x12, 0x26, 0xf6, 0x1c, 0xdf, 0xfe, 0x47, 0xaa, 0xfe, 0x7d, 0x5a,
+    0x17, 0x1f, 0x8d, 0x9a
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_pr_nonce[] = {
+    0x44, 0x82, 0xed, 0xe8, 0x4c, 0x28, 0x5a, 0x14, 0xff, 0x88, 0x8d, 0x19,
+    0x61, 0x5c, 0xee, 0x0f
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_pr_personalizationstring[] = {
+    0x47, 0xd7, 0x9b, 0x99, 0xaa, 0xcb, 0xe7, 0xd2, 0x57, 0x66, 0x2c, 0xe1,
+    0x78, 0xd6, 0x2c, 0xea, 0xa3, 0x23, 0x5f, 0x2a, 0xc1, 0x3a, 0xf0, 0xa4,
+    0x20, 0x3b, 0xfa, 0x07, 0xd5, 0x05, 0x02, 0xe4, 0x57, 0x01, 0xb6, 0x10,
+    0x57, 0x2e, 0xe7, 0x55
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_pr_additionalinput[] = {
+    0x4b, 0x74, 0x0b, 0x40, 0xce, 0x6b, 0xc2, 0x6a, 0x24, 0xb4, 0xf3, 0xad,
+    0x7a, 0xa5, 0x7a, 0xa2, 0x15, 0xe2, 0xc8, 0x61, 0x15, 0xc6, 0xb7, 0x85,
+    0x69, 0x11, 0xad, 0x7b, 0x14, 0xd2, 0xf6, 0x12, 0xa1, 0x95, 0x5d, 0x3f,
+    0xe2, 0xd0, 0x0c, 0x2f
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_pr_entropyinputpr[] = {
+    0x0c, 0x9c, 0xad, 0x05, 0xee, 0xae, 0x48, 0x23, 0x89, 0x59, 0xa1, 0x94,
+    0xd7, 0xd8, 0x75, 0xd5, 0x54, 0x93, 0xc7, 0x4a, 0xd9, 0x26, 0xde, 0xeb,
+    0xba, 0xb0, 0x7e, 0x30, 0x1d, 0x5f, 0x69, 0x40, 0x9c, 0x3b, 0x17, 0x58,
+    0x1d, 0x30, 0xb3, 0x78
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_pr_int_returnedbits[] = {
+    0xf7, 0x93, 0xb0, 0x6d, 0x77, 0x83, 0xd5, 0x38, 0x01, 0xe1, 0x52, 0x40,
+    0x7e, 0x3e, 0x0c, 0x26
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_pr_additionalinput2[] = {
+    0xbc, 0x4b, 0x37, 0x44, 0x1c, 0xc5, 0x45, 0x5f, 0x8f, 0x51, 0x62, 0x8a,
+    0x85, 0x30, 0x1d, 0x7c, 0xe4, 0xcf, 0xf7, 0x44, 0xce, 0x32, 0x3e, 0x57,
+    0x95, 0xa4, 0x2a, 0xdf, 0xfd, 0x9e, 0x38, 0x41, 0xb3, 0xf6, 0xc5, 0xee,
+    0x0c, 0x4b, 0xee, 0x6e
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_pr_entropyinputpr2[] = {
+    0xec, 0xaf, 0xf6, 0x4f, 0xb1, 0xa0, 0x54, 0xb5, 0x5b, 0xe3, 0x46, 0xb0,
+    0x76, 0x5a, 0x7c, 0x3f, 0x7b, 0x94, 0x69, 0x21, 0x51, 0x02, 0xe5, 0x9f,
+    0x04, 0x59, 0x02, 0x98, 0xc6, 0x43, 0x2c, 0xcc, 0x26, 0x4c, 0x87, 0x6b,
+    0x8e, 0x0a, 0x83, 0xdf
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_pr_returnedbits[] = {
+    0x74, 0x45, 0xfb, 0x53, 0x84, 0x96, 0xbe, 0xff, 0x15, 0xcc, 0x41, 0x91,
+    0xb9, 0xa1, 0x21, 0x68
+};
+
+/* AES-192 no df No PR  */
+__fips_constseg static const unsigned char aes_192_no_df_entropyinput[] = {
+    0x3c, 0x7d, 0xb5, 0xe0, 0x54, 0xd9, 0x6e, 0x8c, 0xa9, 0x86, 0xce, 0x4e,
+    0x6b, 0xaf, 0xeb, 0x2f, 0xe7, 0x75, 0xe0, 0x8b, 0xa4, 0x3b, 0x07, 0xfe,
+    0xbe, 0x33, 0x75, 0x93, 0x80, 0x27, 0xb5, 0x29, 0x47, 0x8b, 0xc7, 0x28,
+    0x94, 0xc3, 0x59, 0x63
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_nonce[] = {
+    0x43, 0xf1, 0x7d, 0xb8, 0xc3, 0xfe, 0xd0, 0x23, 0x6b, 0xb4, 0x92, 0xdb,
+    0x29, 0xfd, 0x45, 0x71
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_personalizationstring[] = {
+    0x9f, 0x24, 0x29, 0x99, 0x9e, 0x01, 0xab, 0xe9, 0x19, 0xd8, 0x23, 0x08,
+    0xb7, 0xd6, 0x7e, 0x8c, 0xc0, 0x9e, 0x7f, 0x6e, 0x5b, 0x33, 0x20, 0x96,
+    0x0b, 0x23, 0x2c, 0xa5, 0x6a, 0xf8, 0x1b, 0x04, 0x26, 0xdb, 0x2e, 0x2b,
+    0x3b, 0x88, 0xce, 0x35
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_additionalinput[] = {
+    0x94, 0xe9, 0x7c, 0x3d, 0xa7, 0xdb, 0x60, 0x83, 0x1f, 0x98, 0x3f, 0x0b,
+    0x88, 0x59, 0x57, 0x51, 0x88, 0x9f, 0x76, 0x49, 0x9f, 0xa6, 0xda, 0x71,
+    0x1d, 0x0d, 0x47, 0x16, 0x63, 0xc5, 0x68, 0xe4, 0x5d, 0x39, 0x69, 0xb3,
+    0x3e, 0xbe, 0xd4, 0x8e
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_int_returnedbits[] = {
+    0xf9, 0xd7, 0xad, 0x69, 0xab, 0x8f, 0x23, 0x56, 0x70, 0x17, 0x4f, 0x2a,
+    0x45, 0xe7, 0x4a, 0xc5
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_entropyinputreseed[] = {
+    0xa6, 0x71, 0x6a, 0x3d, 0xba, 0xd1, 0xe8, 0x66, 0xa6, 0xef, 0xb2, 0x0e,
+    0xa8, 0x9c, 0xaa, 0x4e, 0xaf, 0x17, 0x89, 0x50, 0x00, 0xda, 0xa1, 0xb1,
+    0x0b, 0xa4, 0xd9, 0x35, 0x89, 0xc8, 0xe5, 0xb0, 0xd9, 0xb7, 0xc4, 0x33,
+    0x9b, 0xcb, 0x7e, 0x75
+};
+
+__fips_constseg
+    static const unsigned char aes_192_no_df_additionalinputreseed[] = {
+    0x27, 0x21, 0xfc, 0xc2, 0xbd, 0xf3, 0x3c, 0xce, 0xc3, 0xca, 0xc1, 0x01,
+    0xe0, 0xff, 0x93, 0x12, 0x7d, 0x54, 0x42, 0xe3, 0x9f, 0x03, 0xdf, 0x27,
+    0x04, 0x07, 0x3c, 0x53, 0x7f, 0xa8, 0x66, 0xc8, 0x97, 0x4b, 0x61, 0x40,
+    0x5d, 0x7a, 0x25, 0x79
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_additionalinput2[] = {
+    0x2d, 0x8e, 0x16, 0x5d, 0x0b, 0x9f, 0xeb, 0xaa, 0xd6, 0xec, 0x28, 0x71,
+    0x7c, 0x0b, 0xc1, 0x1d, 0xd4, 0x44, 0x19, 0x47, 0xfd, 0x1d, 0x7c, 0xe5,
+    0xf3, 0x27, 0xe1, 0xb6, 0x72, 0x0a, 0xe0, 0xec, 0x0e, 0xcd, 0xef, 0x1a,
+    0x91, 0x6a, 0xe3, 0x5f
+};
+
+__fips_constseg static const unsigned char aes_192_no_df_returnedbits[] = {
+    0xe5, 0xda, 0xb8, 0xe0, 0x63, 0x59, 0x5a, 0xcc, 0x3d, 0xdc, 0x9f, 0xe8,
+    0x66, 0x67, 0x2c, 0x92
+};
+
+/* AES-256 no df PR  */
+__fips_constseg static const unsigned char aes_256_no_df_pr_entropyinput[] = {
+    0x15, 0xc7, 0x5d, 0xcb, 0x41, 0x4b, 0x16, 0x01, 0x3a, 0xd1, 0x44, 0xe8,
+    0x22, 0x32, 0xc6, 0x9c, 0x3f, 0xe7, 0x43, 0xf5, 0x9a, 0xd3, 0xea, 0xf2,
+    0xd7, 0x4e, 0x6e, 0x6a, 0x55, 0x73, 0x40, 0xef, 0x89, 0xad, 0x0d, 0x03,
+    0x96, 0x7e, 0x78, 0x81, 0x2f, 0x91, 0x1b, 0x44, 0xb0, 0x02, 0xba, 0x1c
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_pr_nonce[] = {
+    0xdc, 0xe4, 0xd4, 0x27, 0x7a, 0x90, 0xd7, 0x99, 0x43, 0xa1, 0x3c, 0x30,
+    0xcc, 0x4b, 0xee, 0x2e
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_pr_personalizationstring[] = {
+    0xe3, 0xe6, 0xb9, 0x11, 0xe4, 0x7a, 0xa4, 0x40, 0x6b, 0xf8, 0x73, 0xf7,
+    0x7e, 0xec, 0xc7, 0xb9, 0x97, 0xbf, 0xf8, 0x25, 0x7b, 0xbe, 0x11, 0x9b,
+    0x5b, 0x6a, 0x0c, 0x2e, 0x2b, 0x01, 0x51, 0xcd, 0x41, 0x4b, 0x6b, 0xac,
+    0x31, 0xa8, 0x0b, 0xf7, 0xe6, 0x59, 0x42, 0xb8, 0x03, 0x0c, 0xf8, 0x06
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_pr_additionalinput[] = {
+    0x6a, 0x9f, 0x00, 0x91, 0xae, 0xfe, 0xcf, 0x84, 0x99, 0xce, 0xb1, 0x40,
+    0x6d, 0x5d, 0x33, 0x28, 0x84, 0xf4, 0x8c, 0x63, 0x4c, 0x7e, 0xbd, 0x2c,
+    0x80, 0x76, 0xee, 0x5a, 0xaa, 0x15, 0x07, 0x31, 0xd8, 0xbb, 0x8c, 0x69,
+    0x9d, 0x9d, 0xbc, 0x7e, 0x49, 0xae, 0xec, 0x39, 0x6b, 0xd1, 0x1f, 0x7e
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_pr_entropyinputpr[] = {
+    0xf3, 0xb9, 0x75, 0x9c, 0xbd, 0x88, 0xea, 0xa2, 0x50, 0xad, 0xd6, 0x16,
+    0x1a, 0x12, 0x3c, 0x86, 0x68, 0xaf, 0x6f, 0xbe, 0x19, 0xf2, 0xee, 0xcc,
+    0xa5, 0x70, 0x84, 0x53, 0x50, 0xcb, 0x9f, 0x14, 0xa9, 0xe5, 0xee, 0xb9,
+    0x48, 0x45, 0x40, 0xe2, 0xc7, 0xc9, 0x9a, 0x74, 0xff, 0x8c, 0x99, 0x1f
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_pr_int_returnedbits[] = {
+    0x2e, 0xf2, 0x45, 0x4c, 0x62, 0x2e, 0x0a, 0xb9, 0x6b, 0xa2, 0xfd, 0x56,
+    0x79, 0x60, 0x93, 0xcf
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_pr_additionalinput2[] = {
+    0xaf, 0x69, 0x20, 0xe9, 0x3b, 0x37, 0x9d, 0x3f, 0xb4, 0x80, 0x02, 0x7a,
+    0x25, 0x7d, 0xb8, 0xde, 0x71, 0xc5, 0x06, 0x0c, 0xb4, 0xe2, 0x8f, 0x35,
+    0xd8, 0x14, 0x0d, 0x7f, 0x76, 0x63, 0x4e, 0xb5, 0xee, 0xe9, 0x6f, 0x34,
+    0xc7, 0x5f, 0x56, 0x14, 0x4a, 0xe8, 0x73, 0x95, 0x5b, 0x1c, 0xb9, 0xcb
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_pr_entropyinputpr2[] = {
+    0xe5, 0xb0, 0x2e, 0x7e, 0x52, 0x30, 0xe3, 0x63, 0x82, 0xb6, 0x44, 0xd3,
+    0x25, 0x19, 0x05, 0x24, 0x9a, 0x9f, 0x5f, 0x27, 0x6a, 0x29, 0xab, 0xfa,
+    0x07, 0xa2, 0x42, 0x0f, 0xc5, 0xa8, 0x94, 0x7c, 0x17, 0x7b, 0x85, 0x83,
+    0x0c, 0x25, 0x0e, 0x63, 0x0b, 0xe9, 0x12, 0x60, 0xcd, 0xef, 0x80, 0x0f
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_pr_returnedbits[] = {
+    0x5e, 0xf2, 0x26, 0xef, 0x9f, 0x58, 0x5d, 0xd5, 0x4a, 0x10, 0xfe, 0xa7,
+    0x2d, 0x5f, 0x4a, 0x46
+};
+
+/* AES-256 no df No PR  */
+__fips_constseg static const unsigned char aes_256_no_df_entropyinput[] = {
+    0xfb, 0xcf, 0x1b, 0x61, 0x16, 0x89, 0x78, 0x23, 0xf5, 0xd8, 0x96, 0xe3,
+    0x4e, 0x64, 0x0b, 0x29, 0x9a, 0x3f, 0xf8, 0xa5, 0xed, 0xf2, 0xfe, 0xdb,
+    0x16, 0xca, 0x7f, 0x10, 0xfa, 0x5e, 0x18, 0x76, 0x2c, 0x63, 0x5e, 0x96,
+    0xcf, 0xb3, 0xd6, 0xfc, 0xaf, 0x99, 0x39, 0x28, 0x9c, 0x61, 0xe8, 0xb3
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_nonce[] = {
+    0x12, 0x96, 0xf0, 0x52, 0xf3, 0x8d, 0x81, 0xcf, 0xde, 0x86, 0xf2, 0x99,
+    0x43, 0x96, 0xb9, 0xf0
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_personalizationstring[] = {
+    0x63, 0x0d, 0x78, 0xf5, 0x90, 0x8e, 0x32, 0x47, 0xb0, 0x4d, 0x37, 0x60,
+    0x09, 0x96, 0xbc, 0xbf, 0x97, 0x7a, 0x62, 0x14, 0x45, 0xbd, 0x8d, 0xcc,
+    0x69, 0xfb, 0x03, 0xe1, 0x80, 0x1c, 0xc7, 0xe2, 0x2a, 0xf9, 0x37, 0x3f,
+    0x66, 0x4d, 0x62, 0xd9, 0x10, 0xe0, 0xad, 0xc8, 0x9a, 0xf0, 0xa8, 0x6d
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_additionalinput[] = {
+    0x36, 0xc6, 0x13, 0x60, 0xbb, 0x14, 0xad, 0x22, 0xb0, 0x38, 0xac, 0xa6,
+    0x18, 0x16, 0x93, 0x25, 0x86, 0xb7, 0xdc, 0xdc, 0x36, 0x98, 0x2b, 0xf9,
+    0x68, 0x33, 0xd3, 0xc6, 0xff, 0xce, 0x8d, 0x15, 0x59, 0x82, 0x76, 0xed,
+    0x6f, 0x8d, 0x49, 0x74, 0x2f, 0xda, 0xdc, 0x1f, 0x17, 0xd0, 0xde, 0x17
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_int_returnedbits[] = {
+    0x16, 0x2f, 0x8e, 0x3f, 0x21, 0x7a, 0x1c, 0x20, 0x56, 0xd1, 0x92, 0xf6,
+    0xd2, 0x25, 0x75, 0x0e
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_entropyinputreseed[] = {
+    0x91, 0x79, 0x76, 0xee, 0xe0, 0xcf, 0x9e, 0xc2, 0xd5, 0xd4, 0x23, 0x9b,
+    0x12, 0x8c, 0x7e, 0x0a, 0xb7, 0xd2, 0x8b, 0xd6, 0x7c, 0xa3, 0xc6, 0xe5,
+    0x0e, 0xaa, 0xc7, 0x6b, 0xae, 0x0d, 0xfa, 0x53, 0x06, 0x79, 0xa1, 0xed,
+    0x4d, 0x6a, 0x0e, 0xd8, 0x9d, 0xbe, 0x1b, 0x31, 0x93, 0x7b, 0xec, 0xfb
+};
+
+__fips_constseg
+    static const unsigned char aes_256_no_df_additionalinputreseed[] = {
+    0xd2, 0x46, 0x50, 0x22, 0x10, 0x14, 0x63, 0xf7, 0xea, 0x0f, 0xb9, 0x7e,
+    0x0d, 0xe1, 0x94, 0x07, 0xaf, 0x09, 0x44, 0x31, 0xea, 0x64, 0xa4, 0x18,
+    0x5b, 0xf9, 0xd8, 0xc2, 0xfa, 0x03, 0x47, 0xc5, 0x39, 0x43, 0xd5, 0x3b,
+    0x62, 0x86, 0x64, 0xea, 0x2c, 0x73, 0x8c, 0xae, 0x9d, 0x98, 0x98, 0x29
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_additionalinput2[] = {
+    0x8c, 0xab, 0x18, 0xf8, 0xc3, 0xec, 0x18, 0x5c, 0xb3, 0x1e, 0x9d, 0xbe,
+    0x3f, 0x03, 0xb4, 0x00, 0x98, 0x9d, 0xae, 0xeb, 0xf4, 0x94, 0xf8, 0x42,
+    0x8f, 0xe3, 0x39, 0x07, 0xe1, 0xc9, 0xad, 0x0b, 0x1f, 0xed, 0xc0, 0xba,
+    0xf6, 0xd1, 0xec, 0x27, 0x86, 0x7b, 0xd6, 0x55, 0x9b, 0x60, 0xa5, 0xc6
+};
+
+__fips_constseg static const unsigned char aes_256_no_df_returnedbits[] = {
+    0xef, 0xd2, 0xd8, 0x5c, 0xdc, 0x62, 0x25, 0x9f, 0xaa, 0x1e, 0x2c, 0x67,
+    0xf6, 0x02, 0x32, 0xe2
+};
+
+/* SHA-1 PR  */
+__fips_constseg static const unsigned char sha1_pr_entropyinput[] = {
+    0xd2, 0x36, 0xa5, 0x27, 0x31, 0x73, 0xdd, 0x11, 0x4f, 0x93, 0xbd, 0xe2,
+    0x31, 0xa5, 0x91, 0x13
+};
+
+__fips_constseg static const unsigned char sha1_pr_nonce[] = {
+    0xb5, 0xb3, 0x60, 0xef, 0xf7, 0x63, 0x31, 0xf3
+};
+
+__fips_constseg static const unsigned char sha1_pr_personalizationstring[] = {
+    0xd4, 0xbb, 0x02, 0x10, 0xb2, 0x71, 0xdb, 0x81, 0xd6, 0xf0, 0x42, 0x60,
+    0xda, 0xea, 0x77, 0x52
+};
+
+__fips_constseg static const unsigned char sha1_pr_additionalinput[] = {
+    0x4d, 0xd2, 0x6c, 0x87, 0xfb, 0x2c, 0x4f, 0xa6, 0x8d, 0x16, 0x63, 0x22,
+    0x6a, 0x51, 0xe3, 0xf8
+};
+
+__fips_constseg static const unsigned char sha1_pr_entropyinputpr[] = {
+    0xc9, 0x83, 0x9e, 0x16, 0xf6, 0x1c, 0x0f, 0xb2, 0xec, 0x60, 0x31, 0xa9,
+    0xcb, 0xa9, 0x36, 0x7a
+};
+
+__fips_constseg static const unsigned char sha1_pr_int_returnedbits[] = {
+    0xa8, 0x13, 0x4f, 0xf4, 0x31, 0x02, 0x44, 0xe3, 0xd3, 0x3d, 0x61, 0x9e,
+    0xe5, 0xc6, 0x3e, 0x89, 0xb5, 0x9b, 0x0f, 0x35
+};
+
+__fips_constseg static const unsigned char sha1_pr_additionalinput2[] = {
+    0xf9, 0xe8, 0xd2, 0x72, 0x13, 0x34, 0x95, 0x6f, 0x15, 0x49, 0x47, 0x99,
+    0x16, 0x03, 0x19, 0x47
+};
+
+__fips_constseg static const unsigned char sha1_pr_entropyinputpr2[] = {
+    0x4e, 0x8c, 0x49, 0x9b, 0x4a, 0x5c, 0x9b, 0x9c, 0x3a, 0xee, 0xfb, 0xd2,
+    0xae, 0xcd, 0x8c, 0xc4
+};
+
+__fips_constseg static const unsigned char sha1_pr_returnedbits[] = {
+    0x50, 0xb4, 0xb4, 0xcd, 0x68, 0x57, 0xfc, 0x2e, 0xc1, 0x52, 0xcc, 0xf6,
+    0x68, 0xa4, 0x81, 0xed, 0x7e, 0xe4, 0x1d, 0x87
+};
+
+/* SHA-1 No PR  */
+__fips_constseg static const unsigned char sha1_entropyinput[] = {
+    0xa9, 0x47, 0x1b, 0x29, 0x2d, 0x1c, 0x05, 0xdf, 0x76, 0xd0, 0x62, 0xf9,
+    0xe2, 0x7f, 0x4c, 0x7b
+};
+
+__fips_constseg static const unsigned char sha1_nonce[] = {
+    0x53, 0x23, 0x24, 0xe3, 0xec, 0x0c, 0x54, 0x14
+};
+
+__fips_constseg static const unsigned char sha1_personalizationstring[] = {
+    0x7a, 0x87, 0xa1, 0xac, 0x1c, 0xfd, 0xab, 0xae, 0xf7, 0xd6, 0xfb, 0x76,
+    0x28, 0xec, 0x6d, 0xca
+};
+
+__fips_constseg static const unsigned char sha1_additionalinput[] = {
+    0xfc, 0x92, 0x35, 0xd6, 0x7e, 0xb7, 0x24, 0x65, 0xfd, 0x12, 0x27, 0x35,
+    0xc0, 0x72, 0xca, 0x28
+};
+
+__fips_constseg static const unsigned char sha1_int_returnedbits[] = {
+    0x57, 0x88, 0x82, 0xe5, 0x25, 0xa5, 0x2c, 0x4a, 0x06, 0x20, 0x6c, 0x72,
+    0x55, 0x61, 0xdd, 0x90, 0x71, 0x9f, 0x95, 0xea
+};
+
+__fips_constseg static const unsigned char sha1_entropyinputreseed[] = {
+    0x69, 0xa5, 0x40, 0x62, 0x98, 0x47, 0x56, 0x73, 0x4a, 0x8f, 0x60, 0x96,
+    0xd6, 0x99, 0x27, 0xed
+};
+
+__fips_constseg static const unsigned char sha1_additionalinputreseed[] = {
+    0xe5, 0x40, 0x4e, 0xbd, 0x50, 0x00, 0xf5, 0x15, 0xa6, 0xee, 0x45, 0xda,
+    0x84, 0x3d, 0xd4, 0xc0
+};
+
+__fips_constseg static const unsigned char sha1_additionalinput2[] = {
+    0x11, 0x51, 0x14, 0xf0, 0x09, 0x1b, 0x4e, 0x56, 0x0d, 0xe9, 0xf6, 0x1e,
+    0x52, 0x65, 0xcd, 0x96
+};
+
+__fips_constseg static const unsigned char sha1_returnedbits[] = {
+    0xa1, 0x9c, 0x94, 0x6e, 0x29, 0xe1, 0x33, 0x0d, 0x32, 0xd6, 0xaa, 0xce,
+    0x71, 0x3f, 0x52, 0x72, 0x8b, 0x42, 0xa8, 0xd7
+};
+
+/* SHA-224 PR  */
+__fips_constseg static const unsigned char sha224_pr_entropyinput[] = {
+    0x12, 0x69, 0x32, 0x4f, 0x83, 0xa6, 0xf5, 0x14, 0xe3, 0x49, 0x3e, 0x75,
+    0x3e, 0xde, 0xad, 0xa1, 0x29, 0xc3, 0xf3, 0x19, 0x20, 0xb5, 0x4c, 0xd9
+};
+
+__fips_constseg static const unsigned char sha224_pr_nonce[] = {
+    0x6a, 0x78, 0xd0, 0xeb, 0xbb, 0x5a, 0xf0, 0xee, 0xe8, 0xc3, 0xba, 0x71
+};
+
+__fips_constseg static const unsigned char sha224_pr_personalizationstring[] = {
+    0xd5, 0xb8, 0xb6, 0xbc, 0xc1, 0x5b, 0x60, 0x31, 0x3c, 0xf5, 0xe5, 0xc0,
+    0x8e, 0x52, 0x7a, 0xbd, 0xea, 0x47, 0xa9, 0x5f, 0x8f, 0xf9, 0x8b, 0xae
+};
+
+__fips_constseg static const unsigned char sha224_pr_additionalinput[] = {
+    0x1f, 0x55, 0xec, 0xae, 0x16, 0x12, 0x84, 0xba, 0x84, 0x16, 0x19, 0x88,
+    0x8e, 0xb8, 0x33, 0x25, 0x54, 0xff, 0xca, 0x79, 0xaf, 0x07, 0x25, 0x50
+};
+
+__fips_constseg static const unsigned char sha224_pr_entropyinputpr[] = {
+    0x92, 0xa3, 0x32, 0xa8, 0x9a, 0x0a, 0x58, 0x7c, 0x1d, 0x5a, 0x7e, 0xe1,
+    0xb2, 0x73, 0xab, 0x0e, 0x16, 0x79, 0x23, 0xd3, 0x29, 0x89, 0x81, 0xe1
+};
+
+__fips_constseg static const unsigned char sha224_pr_int_returnedbits[] = {
+    0xf3, 0x38, 0x91, 0x40, 0x37, 0x7a, 0x51, 0x72, 0x42, 0x74, 0x78, 0x0a,
+    0x69, 0xfd, 0xa6, 0x44, 0x43, 0x45, 0x6c, 0x0c, 0x5a, 0x19, 0xff, 0xf1,
+    0x54, 0x60, 0xee, 0x6a
+};
+
+__fips_constseg static const unsigned char sha224_pr_additionalinput2[] = {
+    0x75, 0xf3, 0x04, 0x25, 0xdd, 0x36, 0xa8, 0x37, 0x46, 0xae, 0x0c, 0x52,
+    0x05, 0x79, 0x4c, 0x26, 0xdb, 0xe9, 0x71, 0x16, 0x4c, 0x0a, 0xf2, 0x60
+};
+
+__fips_constseg static const unsigned char sha224_pr_entropyinputpr2[] = {
+    0xea, 0xc5, 0x03, 0x0a, 0x4f, 0xb0, 0x38, 0x8d, 0x23, 0xd4, 0xc8, 0x77,
+    0xe2, 0x6d, 0x9c, 0x0b, 0x44, 0xf7, 0x2d, 0x5b, 0xbf, 0x5d, 0x2a, 0x11
+};
+
+__fips_constseg static const unsigned char sha224_pr_returnedbits[] = {
+    0x60, 0x50, 0x2b, 0xe7, 0x86, 0xd8, 0x26, 0x73, 0xe3, 0x1d, 0x95, 0x20,
+    0xb3, 0x2c, 0x32, 0x1c, 0xf5, 0xce, 0x57, 0xa6, 0x67, 0x2b, 0xdc, 0x4e,
+    0xdd, 0x11, 0x4c, 0xc4
+};
+
+/* SHA-224 No PR  */
+__fips_constseg static const unsigned char sha224_entropyinput[] = {
+    0xb2, 0x1c, 0x77, 0x4d, 0xf6, 0xd3, 0xb6, 0x40, 0xb7, 0x30, 0x3e, 0x29,
+    0xb0, 0x85, 0x1c, 0xbe, 0x4a, 0xea, 0x6b, 0x5a, 0xb5, 0x8a, 0x97, 0xeb
+};
+
+__fips_constseg static const unsigned char sha224_nonce[] = {
+    0x42, 0x02, 0x0a, 0x1c, 0x98, 0x9a, 0x77, 0x9e, 0x9f, 0x80, 0xba, 0xe0
+};
+
+__fips_constseg static const unsigned char sha224_personalizationstring[] = {
+    0x98, 0xb8, 0x04, 0x41, 0xfc, 0xc1, 0x5d, 0xc5, 0xe9, 0xb9, 0x08, 0xda,
+    0xf9, 0xfa, 0x0d, 0x90, 0xce, 0xdf, 0x1d, 0x10, 0xa9, 0x8d, 0x50, 0x0c
+};
+
+__fips_constseg static const unsigned char sha224_additionalinput[] = {
+    0x9a, 0x8d, 0x39, 0x49, 0x42, 0xd5, 0x0b, 0xae, 0xe1, 0xaf, 0xb7, 0x00,
+    0x02, 0xfa, 0x96, 0xb1, 0xa5, 0x1d, 0x2d, 0x25, 0x78, 0xee, 0x83, 0x3f
+};
+
+__fips_constseg static const unsigned char sha224_int_returnedbits[] = {
+    0xe4, 0xf5, 0x53, 0x79, 0x5a, 0x97, 0x58, 0x06, 0x08, 0xba, 0x7b, 0xfa,
+    0xf0, 0x83, 0x05, 0x8c, 0x22, 0xc0, 0xc9, 0xdb, 0x15, 0xe7, 0xde, 0x20,
+    0x55, 0x22, 0x9a, 0xad
+};
+
+__fips_constseg static const unsigned char sha224_entropyinputreseed[] = {
+    0x67, 0x09, 0x48, 0xaa, 0x07, 0x16, 0x99, 0x89, 0x7f, 0x6d, 0xa0, 0xe5,
+    0x8f, 0xdf, 0xbc, 0xdb, 0xfe, 0xe5, 0x6c, 0x7a, 0x95, 0x4a, 0x66, 0x17
+};
+
+__fips_constseg static const unsigned char sha224_additionalinputreseed[] = {
+    0x0f, 0x4b, 0x1c, 0x6f, 0xb7, 0xe3, 0x47, 0xe5, 0x5d, 0x7d, 0x38, 0xd6,
+    0x28, 0x9b, 0xeb, 0x55, 0x63, 0x09, 0x3e, 0x7c, 0x56, 0xea, 0xf8, 0x19
+};
+
+__fips_constseg static const unsigned char sha224_additionalinput2[] = {
+    0x2d, 0x26, 0x7c, 0x37, 0xe4, 0x7a, 0x28, 0x5e, 0x5a, 0x3c, 0xaf, 0x3d,
+    0x5a, 0x8e, 0x55, 0xa2, 0x1a, 0x6e, 0xc0, 0xe5, 0xf6, 0x21, 0xd3, 0xf6
+};
+
+__fips_constseg static const unsigned char sha224_returnedbits[] = {
+    0x4d, 0x83, 0x35, 0xdf, 0x67, 0xa9, 0xfc, 0x17, 0xda, 0x70, 0xcc, 0x8b,
+    0x7f, 0x77, 0xae, 0xa2, 0x5f, 0xb9, 0x7e, 0x74, 0x4c, 0x26, 0xc1, 0x7a,
+    0x3b, 0xa7, 0x5c, 0x93
+};
+
+/* SHA-256 PR  */
+__fips_constseg static const unsigned char sha256_pr_entropyinput[] = {
+    0xce, 0x49, 0x00, 0x7a, 0x56, 0xe3, 0x67, 0x8f, 0xe1, 0xb6, 0xa7, 0xd4,
+    0x4f, 0x08, 0x7a, 0x1b, 0x01, 0xf4, 0xfa, 0x6b, 0xef, 0xb7, 0xe5, 0xeb,
+    0x07, 0x3d, 0x11, 0x0d, 0xc8, 0xea, 0x2b, 0xfe
+};
+
+__fips_constseg static const unsigned char sha256_pr_nonce[] = {
+    0x73, 0x41, 0xc8, 0x92, 0x94, 0xe2, 0xc5, 0x5f, 0x93, 0xfd, 0x39, 0x5d,
+    0x2b, 0x91, 0x4d, 0x38
+};
+
+__fips_constseg static const unsigned char sha256_pr_personalizationstring[] = {
+    0x50, 0x6d, 0x01, 0x01, 0x07, 0x5a, 0x80, 0x35, 0x7a, 0x56, 0x1a, 0x56,
+    0x2f, 0x9a, 0x0b, 0x35, 0xb2, 0xb1, 0xc9, 0xe5, 0xca, 0x69, 0x61, 0x48,
+    0xff, 0xfb, 0x0f, 0xd9, 0x4b, 0x79, 0x1d, 0xba
+};
+
+__fips_constseg static const unsigned char sha256_pr_additionalinput[] = {
+    0x20, 0xb8, 0xdf, 0x44, 0x77, 0x5a, 0xb8, 0xd3, 0xbf, 0xf6, 0xcf, 0xac,
+    0x5e, 0xa6, 0x96, 0x62, 0x73, 0x44, 0x40, 0x4a, 0x30, 0xfb, 0x38, 0xa5,
+    0x7b, 0x0d, 0xe4, 0x0d, 0xc6, 0xe4, 0x9a, 0x1f
+};
+
+__fips_constseg static const unsigned char sha256_pr_entropyinputpr[] = {
+    0x04, 0xc4, 0x65, 0xf4, 0xd3, 0xbf, 0x83, 0x4b, 0xab, 0xc8, 0x41, 0xa8,
+    0xc2, 0xe0, 0x44, 0x63, 0x77, 0x4c, 0x6f, 0x6c, 0x49, 0x46, 0xff, 0x94,
+    0x17, 0xea, 0xe6, 0x1a, 0x9d, 0x5e, 0x66, 0x78
+};
+
+__fips_constseg static const unsigned char sha256_pr_int_returnedbits[] = {
+    0x07, 0x4d, 0xac, 0x9b, 0x86, 0xca, 0x4a, 0xaa, 0x6e, 0x7a, 0x03, 0xa2,
+    0x5d, 0x10, 0xea, 0x0b, 0xf9, 0x83, 0xcc, 0xd1, 0xfc, 0xe2, 0x07, 0xc7,
+    0x06, 0x34, 0x60, 0x6f, 0x83, 0x94, 0x99, 0x76
+};
+
+__fips_constseg static const unsigned char sha256_pr_additionalinput2[] = {
+    0x89, 0x4e, 0x45, 0x8c, 0x11, 0xf9, 0xbc, 0x5b, 0xac, 0x74, 0x8b, 0x4b,
+    0x5f, 0xf7, 0x19, 0xf3, 0xf5, 0x24, 0x54, 0x14, 0xd1, 0x15, 0xb1, 0x43,
+    0x12, 0xa4, 0x5f, 0xd4, 0xec, 0xfc, 0xcd, 0x09
+};
+
+__fips_constseg static const unsigned char sha256_pr_entropyinputpr2[] = {
+    0x0e, 0xeb, 0x1f, 0xd7, 0xfc, 0xd1, 0x9d, 0xd4, 0x05, 0x36, 0x8b, 0xb2,
+    0xfb, 0xe4, 0xf4, 0x51, 0x0c, 0x87, 0x9b, 0x02, 0x44, 0xd5, 0x92, 0x4d,
+    0x44, 0xfe, 0x1a, 0x03, 0x43, 0x56, 0xbd, 0x86
+};
+
+__fips_constseg static const unsigned char sha256_pr_returnedbits[] = {
+    0x02, 0xaa, 0xb6, 0x1d, 0x7e, 0x2a, 0x40, 0x03, 0x69, 0x2d, 0x49, 0xa3,
+    0x41, 0xe7, 0x44, 0x0b, 0xaf, 0x7b, 0x85, 0xe4, 0x5f, 0x53, 0x3b, 0x64,
+    0xbc, 0x89, 0xc8, 0x82, 0xd4, 0x78, 0x37, 0xa2
+};
+
+/* SHA-256 No PR  */
+__fips_constseg static const unsigned char sha256_entropyinput[] = {
+    0x5b, 0x1b, 0xec, 0x4d, 0xa9, 0x38, 0x74, 0x5a, 0x34, 0x0b, 0x7b, 0xc5,
+    0xe5, 0xd7, 0x66, 0x7c, 0xbc, 0x82, 0xb9, 0x0e, 0x2d, 0x1f, 0x92, 0xd7,
+    0xc1, 0xbc, 0x67, 0x69, 0xec, 0x6b, 0x03, 0x3c
+};
+
+__fips_constseg static const unsigned char sha256_nonce[] = {
+    0xa4, 0x0c, 0xd8, 0x9c, 0x61, 0xd8, 0xc3, 0x54, 0xfe, 0x53, 0xc9, 0xe5,
+    0x5d, 0x6f, 0x6d, 0x35
+};
+
+__fips_constseg static const unsigned char sha256_personalizationstring[] = {
+    0x22, 0x5e, 0x62, 0x93, 0x42, 0x83, 0x78, 0x24, 0xd8, 0x40, 0x8c, 0xde,
+    0x6f, 0xf9, 0xa4, 0x7a, 0xc5, 0xa7, 0x3b, 0x88, 0xa3, 0xee, 0x42, 0x20,
+    0xfd, 0x61, 0x56, 0xc6, 0x4c, 0x13, 0x41, 0x9c
+};
+
+__fips_constseg static const unsigned char sha256_additionalinput[] = {
+    0xbf, 0x74, 0x5b, 0xf6, 0xc5, 0x64, 0x5e, 0x99, 0x34, 0x8f, 0xbc, 0xa4,
+    0xe2, 0xbd, 0xd8, 0x85, 0x26, 0x37, 0xea, 0xba, 0x4f, 0xf2, 0x9a, 0x9a,
+    0x66, 0xfc, 0xdf, 0x63, 0x26, 0x26, 0x19, 0x87
+};
+
+__fips_constseg static const unsigned char sha256_int_returnedbits[] = {
+    0xb3, 0xc6, 0x07, 0x07, 0xd6, 0x75, 0xf6, 0x2b, 0xd6, 0x21, 0x96, 0xf1,
+    0xae, 0xdb, 0x2b, 0xac, 0x25, 0x2a, 0xae, 0xae, 0x41, 0x72, 0x03, 0x5e,
+    0xbf, 0xd3, 0x64, 0xbc, 0x59, 0xf9, 0xc0, 0x76
+};
+
+__fips_constseg static const unsigned char sha256_entropyinputreseed[] = {
+    0xbf, 0x20, 0x33, 0x56, 0x29, 0xa8, 0x37, 0x04, 0x1f, 0x78, 0x34, 0x3d,
+    0x81, 0x2a, 0xc9, 0x86, 0xc6, 0x7a, 0x2f, 0x88, 0x5e, 0xd5, 0xbe, 0x34,
+    0x46, 0x20, 0xa4, 0x35, 0xeb, 0xc7, 0xe2, 0x9d
+};
+
+__fips_constseg static const unsigned char sha256_additionalinputreseed[] = {
+    0x9b, 0xae, 0x2d, 0x2d, 0x61, 0xa4, 0x89, 0xeb, 0x43, 0x46, 0xa7, 0xda,
+    0xef, 0x40, 0xca, 0x4a, 0x99, 0x11, 0x41, 0xdc, 0x5c, 0x94, 0xe9, 0xac,
+    0xd4, 0xd0, 0xe6, 0xbd, 0xfb, 0x03, 0x9c, 0xa8
+};
+
+__fips_constseg static const unsigned char sha256_additionalinput2[] = {
+    0x23, 0xaa, 0x0c, 0xbd, 0x28, 0x33, 0xe2, 0x51, 0xfc, 0x71, 0xd2, 0x15,
+    0x1f, 0x76, 0xfd, 0x0d, 0xe0, 0xb7, 0xb5, 0x84, 0x75, 0x5b, 0xbe, 0xf3,
+    0x5c, 0xca, 0xc5, 0x30, 0xf2, 0x75, 0x1f, 0xda
+};
+
+__fips_constseg static const unsigned char sha256_returnedbits[] = {
+    0x90, 0x3c, 0xc1, 0x10, 0x8c, 0x12, 0x01, 0xc6, 0xa6, 0x3a, 0x0f, 0x4d,
+    0xb6, 0x3a, 0x4f, 0x41, 0x9c, 0x61, 0x75, 0x84, 0xe9, 0x74, 0x75, 0xfd,
+    0xfe, 0xf2, 0x1f, 0x43, 0xd8, 0x5e, 0x24, 0xa3
+};
+
+/* SHA-384 PR  */
+__fips_constseg static const unsigned char sha384_pr_entropyinput[] = {
+    0x71, 0x9d, 0xb2, 0x5a, 0x71, 0x6d, 0x04, 0xe9, 0x1e, 0xc7, 0x92, 0x24,
+    0x6e, 0x12, 0x33, 0xa9, 0x52, 0x64, 0x31, 0xef, 0x71, 0xeb, 0x22, 0x55,
+    0x28, 0x97, 0x06, 0x6a, 0xc0, 0x0c, 0xa0, 0x7e
+};
+
+__fips_constseg static const unsigned char sha384_pr_nonce[] = {
+    0xf5, 0x0d, 0xfa, 0xb0, 0xec, 0x6a, 0x7c, 0xd6, 0xbd, 0x9b, 0x05, 0xfd,
+    0x38, 0x3e, 0x2e, 0x56
+};
+
+__fips_constseg static const unsigned char sha384_pr_personalizationstring[] = {
+    0x74, 0xac, 0x7e, 0x6d, 0xb1, 0xa4, 0xe7, 0x21, 0xd1, 0x1e, 0x6e, 0x96,
+    0x6d, 0x4d, 0x53, 0x46, 0x82, 0x96, 0x6e, 0xcf, 0xaa, 0x81, 0x8d, 0x7d,
+    0x9e, 0xe1, 0x0f, 0x15, 0xea, 0x41, 0xbf, 0xe3
+};
+
+__fips_constseg static const unsigned char sha384_pr_additionalinput[] = {
+    0xda, 0x95, 0xd4, 0xd0, 0xb8, 0x11, 0xd3, 0x49, 0x27, 0x5d, 0xa9, 0x39,
+    0x68, 0xf3, 0xa8, 0xe9, 0x5d, 0x19, 0x8a, 0x2b, 0x66, 0xe8, 0x69, 0x06,
+    0x7c, 0x9e, 0x03, 0xa1, 0x8b, 0x26, 0x2d, 0x6e
+};
+
+__fips_constseg static const unsigned char sha384_pr_entropyinputpr[] = {
+    0x49, 0xdf, 0x44, 0x00, 0xe4, 0x1c, 0x75, 0x0b, 0x26, 0x5a, 0x59, 0x64,
+    0x1f, 0x4e, 0xb1, 0xb2, 0x13, 0xf1, 0x22, 0x4e, 0xb4, 0x6d, 0x9a, 0xcc,
+    0xa0, 0x48, 0xe6, 0xcf, 0x1d, 0xd1, 0x92, 0x0d
+};
+
+__fips_constseg static const unsigned char sha384_pr_int_returnedbits[] = {
+    0xc8, 0x52, 0xae, 0xbf, 0x04, 0x3c, 0x27, 0xb7, 0x78, 0x18, 0xaa, 0x8f,
+    0xff, 0xcf, 0xa4, 0xf1, 0xcc, 0xe7, 0x68, 0xfa, 0x22, 0xa2, 0x13, 0x45,
+    0xe8, 0xdd, 0x87, 0xe6, 0xf2, 0x6e, 0xdd, 0xc7, 0x52, 0x90, 0x9f, 0x7b,
+    0xfa, 0x61, 0x2d, 0x9d, 0x9e, 0xcf, 0x98, 0xac, 0x52, 0x40, 0xce, 0xaf
+};
+
+__fips_constseg static const unsigned char sha384_pr_additionalinput2[] = {
+    0x61, 0x7c, 0x03, 0x9a, 0x3e, 0x50, 0x57, 0x60, 0xc5, 0x83, 0xc9, 0xb2,
+    0xd1, 0x87, 0x85, 0x66, 0x92, 0x5d, 0x84, 0x0e, 0x53, 0xfb, 0x70, 0x03,
+    0x72, 0xfd, 0xba, 0xae, 0x9c, 0x8f, 0xf8, 0x18
+};
+
+__fips_constseg static const unsigned char sha384_pr_entropyinputpr2[] = {
+    0xf8, 0xeb, 0x89, 0xb1, 0x8d, 0x78, 0xbe, 0x21, 0xe0, 0xbb, 0x9d, 0xb7,
+    0x95, 0x0e, 0xd9, 0x46, 0x0c, 0x8c, 0xe2, 0x63, 0xb7, 0x9d, 0x67, 0x90,
+    0xbd, 0xc7, 0x0b, 0xa5, 0xce, 0xb2, 0x65, 0x81
+};
+
+__fips_constseg static const unsigned char sha384_pr_returnedbits[] = {
+    0xe6, 0x9f, 0xfe, 0x68, 0xd6, 0xb5, 0x79, 0xf1, 0x06, 0x5f, 0xa3, 0xbb,
+    0x23, 0x85, 0xd8, 0xf0, 0x29, 0x5a, 0x68, 0x9e, 0xf5, 0xf4, 0xa6, 0x12,
+    0xe0, 0x9a, 0xe2, 0xac, 0x00, 0x1d, 0x98, 0x26, 0xfc, 0x53, 0x95, 0x53,
+    0xe4, 0x3e, 0x17, 0xd5, 0x08, 0x0b, 0x70, 0x3d, 0x67, 0x99, 0xac, 0x66
+};
+
+/* SHA-384 No PR  */
+__fips_constseg static const unsigned char sha384_entropyinput[] = {
+    0x07, 0x15, 0x27, 0x2a, 0xaf, 0x74, 0x24, 0x37, 0xbc, 0xd5, 0x14, 0x69,
+    0xce, 0x11, 0xff, 0xa2, 0x6b, 0xb8, 0x05, 0x67, 0x34, 0xf8, 0xbd, 0x6d,
+    0x6a, 0xcc, 0xcd, 0x60, 0xa3, 0x68, 0xca, 0xf4
+};
+
+__fips_constseg static const unsigned char sha384_nonce[] = {
+    0x70, 0x17, 0xc2, 0x5b, 0x5d, 0x22, 0x0b, 0x06, 0x15, 0x54, 0x78, 0x77,
+    0x44, 0xaf, 0x2f, 0x09
+};
+
+__fips_constseg static const unsigned char sha384_personalizationstring[] = {
+    0x89, 0x39, 0x28, 0xb0, 0x60, 0xeb, 0x3d, 0xdc, 0x55, 0x75, 0x86, 0xeb,
+    0xae, 0xa2, 0x8f, 0xbc, 0x1b, 0x75, 0xd4, 0xe1, 0x0f, 0xaa, 0x38, 0xca,
+    0x62, 0x8b, 0xcb, 0x2c, 0x26, 0xf6, 0xbc, 0xb1
+};
+
+__fips_constseg static const unsigned char sha384_additionalinput[] = {
+    0x30, 0x2b, 0x42, 0x35, 0xef, 0xda, 0x40, 0x55, 0x28, 0xc6, 0x95, 0xfb,
+    0x54, 0x01, 0x62, 0xd7, 0x87, 0x14, 0x48, 0x6d, 0x90, 0x4c, 0xa9, 0x02,
+    0x54, 0x40, 0x22, 0xc8, 0x66, 0xa5, 0x48, 0x48
+};
+
+__fips_constseg static const unsigned char sha384_int_returnedbits[] = {
+    0x82, 0xc4, 0xa1, 0x9c, 0x21, 0xd2, 0xe7, 0xa5, 0xa6, 0xf6, 0x5f, 0x04,
+    0x5c, 0xc7, 0x31, 0x9d, 0x8d, 0x59, 0x74, 0x50, 0x19, 0x89, 0x2f, 0x63,
+    0xd5, 0xb7, 0x7e, 0xeb, 0x15, 0xe3, 0x70, 0x83, 0xa1, 0x24, 0x59, 0xfa,
+    0x2c, 0x56, 0xf6, 0x88, 0x3a, 0x92, 0x93, 0xa1, 0xfb, 0x79, 0xc1, 0x7a
+};
+
+__fips_constseg static const unsigned char sha384_entropyinputreseed[] = {
+    0x39, 0xa6, 0xe8, 0x5c, 0x82, 0x17, 0x71, 0x26, 0x57, 0x4f, 0x9f, 0xc2,
+    0x55, 0xff, 0x5c, 0x9b, 0x53, 0x1a, 0xd1, 0x5f, 0xbc, 0x62, 0xe4, 0x27,
+    0x2d, 0x32, 0xf0, 0xe4, 0x52, 0x8c, 0xc5, 0x0c
+};
+
+__fips_constseg static const unsigned char sha384_additionalinputreseed[] = {
+    0x8d, 0xcb, 0x8d, 0xce, 0x08, 0xea, 0x80, 0xe8, 0x9b, 0x61, 0xa8, 0x0f,
+    0xaf, 0x49, 0x20, 0x9e, 0x74, 0xcb, 0x57, 0x80, 0x42, 0xb0, 0x84, 0x5e,
+    0x30, 0x2a, 0x67, 0x08, 0xf4, 0xe3, 0x40, 0x22
+};
+
+__fips_constseg static const unsigned char sha384_additionalinput2[] = {
+    0x7c, 0x8f, 0xc2, 0xae, 0x22, 0x4a, 0xd6, 0xf6, 0x05, 0xa4, 0x7a, 0xea,
+    0xbb, 0x25, 0xd0, 0xb7, 0x5a, 0xd6, 0xcf, 0x9d, 0xf3, 0x6c, 0xe2, 0xb2,
+    0x4e, 0xb4, 0xbd, 0xf4, 0xe5, 0x40, 0x80, 0x94
+};
+
+__fips_constseg static const unsigned char sha384_returnedbits[] = {
+    0x9e, 0x7e, 0xfb, 0x59, 0xbb, 0xaa, 0x3c, 0xf7, 0xe1, 0xf8, 0x76, 0xdd,
+    0x63, 0x5f, 0xaf, 0x23, 0xd6, 0x64, 0x61, 0xc0, 0x9a, 0x09, 0x47, 0xc9,
+    0x33, 0xdf, 0x6d, 0x55, 0x91, 0x34, 0x79, 0x70, 0xc4, 0x99, 0x6e, 0x54,
+    0x09, 0x64, 0x21, 0x1a, 0xbd, 0x1e, 0x80, 0x40, 0x34, 0xad, 0xfa, 0xd7
+};
+
+/* SHA-512 PR  */
+__fips_constseg static const unsigned char sha512_pr_entropyinput[] = {
+    0x13, 0xf7, 0x61, 0x75, 0x65, 0x28, 0xa2, 0x59, 0x13, 0x5a, 0x4a, 0x4f,
+    0x56, 0x60, 0x8c, 0x53, 0x7d, 0xb0, 0xbd, 0x06, 0x4f, 0xed, 0xcc, 0xd2,
+    0xa2, 0xb5, 0xfd, 0x5b, 0x3a, 0xab, 0xec, 0x28
+};
+
+__fips_constseg static const unsigned char sha512_pr_nonce[] = {
+    0xbe, 0xa3, 0x91, 0x93, 0x1d, 0xc3, 0x31, 0x3a, 0x23, 0x33, 0x50, 0x67,
+    0x88, 0xc7, 0xa2, 0xc4
+};
+
+__fips_constseg static const unsigned char sha512_pr_personalizationstring[] = {
+    0x1f, 0x59, 0x4d, 0x7b, 0xe6, 0x46, 0x91, 0x48, 0xc1, 0x25, 0xfa, 0xff,
+    0x89, 0x12, 0x77, 0x35, 0xdf, 0x3e, 0xf4, 0x80, 0x5f, 0xd9, 0xb0, 0x07,
+    0x22, 0x41, 0xdd, 0x48, 0x78, 0x6b, 0x77, 0x2b
+};
+
+__fips_constseg static const unsigned char sha512_pr_additionalinput[] = {
+    0x30, 0xff, 0x63, 0x6f, 0xac, 0xd9, 0x84, 0x39, 0x6f, 0xe4, 0x99, 0xce,
+    0x91, 0x7d, 0x7e, 0xc8, 0x58, 0xf2, 0x12, 0xc3, 0xb6, 0xad, 0xda, 0x22,
+    0x04, 0xa0, 0xd2, 0x21, 0xfe, 0xf2, 0x95, 0x1d
+};
+
+__fips_constseg static const unsigned char sha512_pr_entropyinputpr[] = {
+    0x64, 0x54, 0x13, 0xec, 0x4f, 0x77, 0xda, 0xb2, 0x92, 0x2e, 0x52, 0x80,
+    0x11, 0x10, 0xc2, 0xf8, 0xe6, 0xa7, 0xcd, 0x4b, 0xfc, 0x32, 0x2e, 0x9e,
+    0xeb, 0xbb, 0xb1, 0xbf, 0x15, 0x5c, 0x73, 0x08
+};
+
+__fips_constseg static const unsigned char sha512_pr_int_returnedbits[] = {
+    0xef, 0x1e, 0xdc, 0x0a, 0xa4, 0x36, 0x91, 0x9c, 0x3d, 0x27, 0x97, 0x50,
+    0x8d, 0x36, 0x29, 0x8d, 0xce, 0x6a, 0x0c, 0xf7, 0x21, 0xc0, 0x91, 0xae,
+    0x0c, 0x96, 0x72, 0xbd, 0x52, 0x81, 0x58, 0xfc, 0x6d, 0xe5, 0xf7, 0xa5,
+    0xfd, 0x5d, 0xa7, 0x58, 0x68, 0xc8, 0x99, 0x58, 0x8e, 0xc8, 0xce, 0x95,
+    0x01, 0x7d, 0xff, 0xa4, 0xc8, 0xf7, 0x63, 0xfe, 0x5f, 0x69, 0x83, 0x53,
+    0xe2, 0xc6, 0x8b, 0xc3
+};
+
+__fips_constseg static const unsigned char sha512_pr_additionalinput2[] = {
+    0xe6, 0x9b, 0xc4, 0x88, 0x34, 0xca, 0xea, 0x29, 0x2f, 0x98, 0x05, 0xa4,
+    0xd3, 0xc0, 0x7b, 0x11, 0xe8, 0xbb, 0x75, 0xf2, 0xbd, 0x29, 0xb7, 0x40,
+    0x25, 0x7f, 0xc1, 0xb7, 0xb1, 0xf1, 0x25, 0x61
+};
+
+__fips_constseg static const unsigned char sha512_pr_entropyinputpr2[] = {
+    0x23, 0x6d, 0xff, 0xde, 0xfb, 0xd1, 0xba, 0x33, 0x18, 0xe6, 0xbe, 0xb5,
+    0x48, 0x77, 0x6d, 0x7f, 0xa7, 0xe1, 0x4d, 0x48, 0x1e, 0x3c, 0xa7, 0x34,
+    0x1a, 0xc8, 0x60, 0xdb, 0x8f, 0x99, 0x15, 0x99
+};
+
+__fips_constseg static const unsigned char sha512_pr_returnedbits[] = {
+    0x70, 0x27, 0x31, 0xdb, 0x92, 0x70, 0x21, 0xfe, 0x16, 0xb6, 0xc8, 0x51,
+    0x34, 0x87, 0x65, 0xd0, 0x4e, 0xfd, 0xfe, 0x68, 0xec, 0xac, 0xdc, 0x93,
+    0x41, 0x38, 0x92, 0x90, 0xb4, 0x94, 0xf9, 0x0d, 0xa4, 0xf7, 0x4e, 0x80,
+    0x92, 0x67, 0x48, 0x40, 0xa7, 0x08, 0xc7, 0xbc, 0x66, 0x00, 0xfd, 0xf7,
+    0x4c, 0x8b, 0x17, 0x6e, 0xd1, 0x8f, 0x9b, 0xf3, 0x6f, 0xf6, 0x34, 0xdd,
+    0x67, 0xf7, 0x68, 0xdd
+};
+
+/* SHA-512 No PR  */
+__fips_constseg static const unsigned char sha512_entropyinput[] = {
+    0xb6, 0x0b, 0xb7, 0xbc, 0x84, 0x56, 0xf6, 0x12, 0xaf, 0x45, 0x67, 0x17,
+    0x7c, 0xd1, 0xb2, 0x78, 0x2b, 0xa0, 0xf2, 0xbe, 0xb6, 0x6d, 0x8b, 0x56,
+    0xc6, 0xbc, 0x4d, 0xe1, 0xf7, 0xbe, 0xce, 0xbd
+};
+
+__fips_constseg static const unsigned char sha512_nonce[] = {
+    0x9d, 0xed, 0xc0, 0xe5, 0x5a, 0x98, 0x6a, 0xcb, 0x51, 0x7d, 0x76, 0x31,
+    0x5a, 0x64, 0xf0, 0xf7
+};
+
+__fips_constseg static const unsigned char sha512_personalizationstring[] = {
+    0xc2, 0x6d, 0xa3, 0xc3, 0x06, 0x74, 0xe5, 0x01, 0x5c, 0x10, 0x17, 0xc7,
+    0xaf, 0x83, 0x9d, 0x59, 0x8d, 0x2d, 0x29, 0x38, 0xc5, 0x59, 0x70, 0x8b,
+    0x46, 0x48, 0x2d, 0xcf, 0x36, 0x7d, 0x59, 0xc0
+};
+
+__fips_constseg static const unsigned char sha512_additionalinput[] = {
+    0xec, 0x8c, 0xd4, 0xf7, 0x61, 0x6e, 0x0d, 0x95, 0x79, 0xb7, 0x28, 0xad,
+    0x5f, 0x69, 0x74, 0x5f, 0x2d, 0x36, 0x06, 0x8a, 0x6b, 0xac, 0x54, 0x97,
+    0xc4, 0xa1, 0x12, 0x85, 0x0a, 0xdf, 0x4b, 0x34
+};
+
+__fips_constseg static const unsigned char sha512_int_returnedbits[] = {
+    0x84, 0x2f, 0x1f, 0x68, 0x6a, 0xa3, 0xad, 0x1e, 0xfb, 0xf4, 0x15, 0xbd,
+    0xde, 0x38, 0xd4, 0x30, 0x80, 0x51, 0xe9, 0xd3, 0xc7, 0x20, 0x88, 0xe9,
+    0xf5, 0xcc, 0xdf, 0x57, 0x5c, 0x47, 0x2f, 0x57, 0x3c, 0x5f, 0x13, 0x56,
+    0xcc, 0xc5, 0x4f, 0x84, 0xf8, 0x10, 0x41, 0xd5, 0x7e, 0x58, 0x6e, 0x19,
+    0x19, 0x9e, 0xaf, 0xc2, 0x22, 0x58, 0x41, 0x50, 0x79, 0xc2, 0xd8, 0x04,
+    0x28, 0xd4, 0x39, 0x9a
+};
+
+__fips_constseg static const unsigned char sha512_entropyinputreseed[] = {
+    0xfa, 0x7f, 0x46, 0x51, 0x83, 0x62, 0x98, 0x16, 0x9a, 0x19, 0xa2, 0x49,
+    0xa9, 0xe6, 0x4a, 0xd8, 0x85, 0xe7, 0xd4, 0x3b, 0x2c, 0x82, 0xc5, 0x82,
+    0xbf, 0x11, 0xf9, 0x9e, 0xbc, 0xd0, 0x01, 0xee
+};
+
+__fips_constseg static const unsigned char sha512_additionalinputreseed[] = {
+    0xb9, 0x12, 0xe0, 0x4f, 0xf7, 0xa7, 0xc4, 0xd8, 0xd0, 0x8e, 0x99, 0x29,
+    0x7c, 0x9a, 0xe9, 0xcf, 0xc4, 0x6c, 0xf8, 0xc3, 0xa7, 0x41, 0x83, 0xd6,
+    0x2e, 0xfa, 0xb8, 0x5e, 0x8e, 0x6b, 0x78, 0x20
+};
+
+__fips_constseg static const unsigned char sha512_additionalinput2[] = {
+    0xd7, 0x07, 0x52, 0xb9, 0x83, 0x2c, 0x03, 0x71, 0xee, 0xc9, 0xc0, 0x85,
+    0xe1, 0x57, 0xb2, 0xcd, 0x3a, 0xf0, 0xc9, 0x34, 0x24, 0x41, 0x1c, 0x42,
+    0x99, 0xb2, 0x84, 0xe9, 0x17, 0xd2, 0x76, 0x92
+};
+
+__fips_constseg static const unsigned char sha512_returnedbits[] = {
+    0x36, 0x17, 0x5d, 0x98, 0x2b, 0x65, 0x25, 0x8e, 0xc8, 0x29, 0xdf, 0x27,
+    0x05, 0x36, 0x26, 0x12, 0x8a, 0x68, 0x74, 0x27, 0x37, 0xd4, 0x7f, 0x32,
+    0xb1, 0x12, 0xd6, 0x85, 0x83, 0xeb, 0x2e, 0xa0, 0xed, 0x4b, 0xb5, 0x7b,
+    0x6f, 0x39, 0x3c, 0x71, 0x77, 0x02, 0x12, 0xcc, 0x2c, 0x3a, 0x8e, 0x63,
+    0xdf, 0x4a, 0xbd, 0x6f, 0x6e, 0x2e, 0xed, 0x0a, 0x85, 0xa5, 0x2f, 0xa2,
+    0x68, 0xde, 0x42, 0xb5
+};
+
+/* HMAC SHA-1 PR  */
+__fips_constseg static const unsigned char hmac_sha1_pr_entropyinput[] = {
+    0x26, 0x5f, 0x36, 0x14, 0xff, 0x3d, 0x83, 0xfa, 0x73, 0x5e, 0x75, 0xdc,
+    0x2c, 0x18, 0x17, 0x1b
+};
+
+__fips_constseg static const unsigned char hmac_sha1_pr_nonce[] = {
+    0xc8, 0xe3, 0x57, 0xa5, 0x7b, 0x74, 0x86, 0x6e
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha1_pr_personalizationstring[] = {
+    0x6e, 0xdb, 0x0d, 0xfe, 0x7d, 0xac, 0x79, 0xd0, 0xa5, 0x3a, 0x48, 0x85,
+    0x80, 0xe2, 0x7f, 0x2a
+};
+
+__fips_constseg static const unsigned char hmac_sha1_pr_additionalinput[] = {
+    0x31, 0xcd, 0x5e, 0x43, 0xdc, 0xfb, 0x7a, 0x79, 0xca, 0x88, 0xde, 0x1f,
+    0xd7, 0xbb, 0x42, 0x09
+};
+
+__fips_constseg static const unsigned char hmac_sha1_pr_entropyinputpr[] = {
+    0x7c, 0x23, 0x95, 0x38, 0x00, 0x95, 0xc1, 0x78, 0x1f, 0x8f, 0xd7, 0x63,
+    0x23, 0x87, 0x2a, 0xed
+};
+
+__fips_constseg static const unsigned char hmac_sha1_pr_int_returnedbits[] = {
+    0xbb, 0x34, 0xe7, 0x93, 0xa3, 0x02, 0x2c, 0x4a, 0xd0, 0x89, 0xda, 0x7f,
+    0xed, 0xf4, 0x4c, 0xde, 0x17, 0xec, 0xe5, 0x6c
+};
+
+__fips_constseg static const unsigned char hmac_sha1_pr_additionalinput2[] = {
+    0x49, 0xbc, 0x2d, 0x2c, 0xb7, 0x32, 0xcb, 0x20, 0xdf, 0xf5, 0x77, 0x58,
+    0xa0, 0x4b, 0x93, 0x6e
+};
+
+__fips_constseg static const unsigned char hmac_sha1_pr_entropyinputpr2[] = {
+    0x3c, 0xaa, 0xb0, 0x21, 0x42, 0xb0, 0xdd, 0x34, 0xf0, 0x16, 0x7f, 0x0c,
+    0x0f, 0xff, 0x2e, 0xaf
+};
+
+__fips_constseg static const unsigned char hmac_sha1_pr_returnedbits[] = {
+    0x8e, 0xcb, 0xa3, 0x64, 0xb2, 0xb8, 0x33, 0x6c, 0x64, 0x3b, 0x78, 0x16,
+    0x99, 0x35, 0xc8, 0x30, 0xcb, 0x3e, 0xa0, 0xd8
+};
+
+/* HMAC SHA-1 No PR  */
+__fips_constseg static const unsigned char hmac_sha1_entropyinput[] = {
+    0x32, 0x9a, 0x2a, 0x87, 0x7b, 0x89, 0x7c, 0xf6, 0xcb, 0x95, 0xd5, 0x40,
+    0x17, 0xfe, 0x47, 0x70
+};
+
+__fips_constseg static const unsigned char hmac_sha1_nonce[] = {
+    0x16, 0xd8, 0xe0, 0xc7, 0x52, 0xcf, 0x4a, 0x25
+};
+
+__fips_constseg static const unsigned char hmac_sha1_personalizationstring[] = {
+    0x35, 0x35, 0xa9, 0xa5, 0x40, 0xbe, 0x9b, 0xd1, 0x56, 0xdd, 0x44, 0x00,
+    0x72, 0xf7, 0xd3, 0x5e
+};
+
+__fips_constseg static const unsigned char hmac_sha1_additionalinput[] = {
+    0x1b, 0x2c, 0x84, 0x2d, 0x4a, 0x89, 0x8f, 0x69, 0x19, 0xf1, 0xf3, 0xdb,
+    0xbb, 0xe3, 0xaa, 0xea
+};
+
+__fips_constseg static const unsigned char hmac_sha1_int_returnedbits[] = {
+    0xcf, 0xfa, 0x7d, 0x72, 0x0f, 0xe6, 0xc7, 0x96, 0xa0, 0x69, 0x31, 0x11,
+    0x9b, 0x0b, 0x1a, 0x20, 0x1f, 0x3f, 0xaa, 0xd1
+};
+
+__fips_constseg static const unsigned char hmac_sha1_entropyinputreseed[] = {
+    0x90, 0x75, 0x15, 0x04, 0x95, 0xf1, 0xba, 0x81, 0x0c, 0x37, 0x94, 0x6f,
+    0x86, 0x52, 0x6d, 0x9c
+};
+
+__fips_constseg static const unsigned char hmac_sha1_additionalinputreseed[] = {
+    0x5b, 0x40, 0xba, 0x5f, 0x17, 0x70, 0xf0, 0x4b, 0xdf, 0xc9, 0x97, 0x92,
+    0x79, 0xc5, 0x82, 0x28
+};
+
+__fips_constseg static const unsigned char hmac_sha1_additionalinput2[] = {
+    0x97, 0xc8, 0x80, 0x90, 0xb3, 0xaa, 0x6e, 0x60, 0xea, 0x83, 0x7a, 0xe3,
+    0x8a, 0xca, 0xa4, 0x7f
+};
+
+__fips_constseg static const unsigned char hmac_sha1_returnedbits[] = {
+    0x90, 0xbd, 0x05, 0x56, 0x6d, 0xb5, 0x22, 0xd5, 0xb9, 0x5a, 0x29, 0x2d,
+    0xe9, 0x0b, 0xe1, 0xac, 0xde, 0x27, 0x0b, 0xb0
+};
+
+/* HMAC SHA-224 PR  */
+__fips_constseg static const unsigned char hmac_sha224_pr_entropyinput[] = {
+    0x17, 0x32, 0x2b, 0x2e, 0x6f, 0x1b, 0x9c, 0x6d, 0x31, 0xe0, 0x34, 0x07,
+    0xcf, 0xed, 0xf6, 0xb6, 0x5a, 0x76, 0x4c, 0xbc, 0x62, 0x85, 0x01, 0x90
+};
+
+__fips_constseg static const unsigned char hmac_sha224_pr_nonce[] = {
+    0x38, 0xbf, 0x5f, 0x20, 0xb3, 0x68, 0x2f, 0x43, 0x61, 0x05, 0x8f, 0x23
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha224_pr_personalizationstring[] = {
+    0xc0, 0xc9, 0x45, 0xac, 0x8d, 0x27, 0x77, 0x08, 0x0b, 0x17, 0x6d, 0xed,
+    0xc1, 0x7d, 0xd5, 0x07, 0x9d, 0x6e, 0xf8, 0x23, 0x2a, 0x22, 0x13, 0xbd
+};
+
+__fips_constseg static const unsigned char hmac_sha224_pr_additionalinput[] = {
+    0xa4, 0x3c, 0xe7, 0x3b, 0xea, 0x19, 0x45, 0x32, 0xc2, 0x83, 0x6d, 0x21,
+    0x8a, 0xc0, 0xee, 0x67, 0x45, 0xde, 0x13, 0x7d, 0x9d, 0x61, 0x00, 0x3b
+};
+
+__fips_constseg static const unsigned char hmac_sha224_pr_entropyinputpr[] = {
+    0x15, 0x05, 0x74, 0x4a, 0x7f, 0x8d, 0x5c, 0x60, 0x16, 0xe5, 0x7b, 0xad,
+    0xf5, 0x41, 0x8f, 0x55, 0x60, 0xc4, 0x09, 0xee, 0x1e, 0x11, 0x81, 0xab
+};
+
+__fips_constseg static const unsigned char hmac_sha224_pr_int_returnedbits[] = {
+    0x6f, 0xf5, 0x9a, 0xe2, 0x54, 0x53, 0x30, 0x3d, 0x5a, 0x27, 0x29, 0x38,
+    0x27, 0xf2, 0x0d, 0x05, 0xe9, 0x26, 0xcb, 0x16, 0xc3, 0x51, 0x5f, 0x13,
+    0x41, 0xfe, 0x99, 0xf2
+};
+
+__fips_constseg static const unsigned char hmac_sha224_pr_additionalinput2[] = {
+    0x73, 0x81, 0x88, 0x84, 0x8f, 0xed, 0x6f, 0x10, 0x9f, 0x93, 0xbf, 0x17,
+    0x35, 0x7c, 0xef, 0xd5, 0x8d, 0x26, 0xa6, 0x7a, 0xe8, 0x09, 0x36, 0x4f
+};
+
+__fips_constseg static const unsigned char hmac_sha224_pr_entropyinputpr2[] = {
+    0xe6, 0xcf, 0xcf, 0x7e, 0x12, 0xe5, 0x43, 0xd2, 0x38, 0xd8, 0x24, 0x6f,
+    0x5a, 0x37, 0x68, 0xbf, 0x4f, 0xa0, 0xff, 0xd5, 0x61, 0x8a, 0x93, 0xe0
+};
+
+__fips_constseg static const unsigned char hmac_sha224_pr_returnedbits[] = {
+    0xaf, 0xf9, 0xd8, 0x19, 0x91, 0x30, 0x82, 0x6f, 0xa9, 0x1e, 0x9d, 0xd7,
+    0xf3, 0x50, 0xe0, 0xc7, 0xd5, 0x64, 0x96, 0x7d, 0x4c, 0x4d, 0x78, 0x03,
+    0x6d, 0xd8, 0x9e, 0x72
+};
+
+/* HMAC SHA-224 No PR  */
+__fips_constseg static const unsigned char hmac_sha224_entropyinput[] = {
+    0x11, 0x82, 0xfd, 0xd9, 0x42, 0xf4, 0xfa, 0xc8, 0xf2, 0x41, 0xe6, 0x54,
+    0x01, 0xae, 0x22, 0x6e, 0xc6, 0xaf, 0xaf, 0xd0, 0xa6, 0xb2, 0xe2, 0x6d
+};
+
+__fips_constseg static const unsigned char hmac_sha224_nonce[] = {
+    0xa9, 0x48, 0xd7, 0x92, 0x39, 0x7e, 0x2a, 0xdc, 0x30, 0x1f, 0x0e, 0x2b
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha224_personalizationstring[] = {
+    0x11, 0xd5, 0xf4, 0xbd, 0x67, 0x8c, 0x31, 0xcf, 0xa3, 0x3f, 0x1e, 0x6b,
+    0xa8, 0x07, 0x02, 0x0b, 0xc8, 0x2e, 0x6c, 0x64, 0x41, 0x5b, 0xc8, 0x37
+};
+
+__fips_constseg static const unsigned char hmac_sha224_additionalinput[] = {
+    0x68, 0x18, 0xc2, 0x06, 0xeb, 0x3e, 0x04, 0x95, 0x44, 0x5e, 0xfb, 0xe6,
+    0x41, 0xc1, 0x5c, 0xcc, 0x40, 0x2f, 0xb7, 0xd2, 0x0f, 0xf3, 0x6b, 0xe7
+};
+
+__fips_constseg static const unsigned char hmac_sha224_int_returnedbits[] = {
+    0x7f, 0x45, 0xc7, 0x5d, 0x32, 0xe6, 0x17, 0x60, 0xba, 0xdc, 0xb8, 0x42,
+    0x1b, 0x9c, 0xf1, 0xfa, 0x3b, 0x4d, 0x29, 0x54, 0xc6, 0x90, 0xff, 0x5c,
+    0xcd, 0xd6, 0xa9, 0xcc
+};
+
+__fips_constseg static const unsigned char hmac_sha224_entropyinputreseed[] = {
+    0xc4, 0x8e, 0x37, 0x95, 0x69, 0x53, 0x28, 0xd7, 0x37, 0xbb, 0x70, 0x95,
+    0x1c, 0x07, 0x1d, 0xd9, 0xb7, 0xe6, 0x1b, 0xbb, 0xfe, 0x41, 0xeb, 0xc9
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha224_additionalinputreseed[] = {
+    0x53, 0x17, 0xa1, 0x6a, 0xfa, 0x77, 0x47, 0xb0, 0x95, 0x56, 0x9a, 0x20,
+    0x57, 0xde, 0x5c, 0x89, 0x9f, 0x7f, 0xe2, 0xde, 0x17, 0x3a, 0x50, 0x23
+};
+
+__fips_constseg static const unsigned char hmac_sha224_additionalinput2[] = {
+    0x3a, 0x32, 0xf9, 0x85, 0x0c, 0xc1, 0xed, 0x76, 0x2d, 0xdf, 0x40, 0xc3,
+    0x06, 0x22, 0x66, 0xd4, 0x9a, 0x9a, 0xff, 0x5a, 0x7e, 0x7a, 0xf3, 0x96
+};
+
+__fips_constseg static const unsigned char hmac_sha224_returnedbits[] = {
+    0x43, 0xb4, 0x57, 0x5c, 0x38, 0x25, 0x9d, 0xae, 0xec, 0x96, 0xd1, 0x85,
+    0x3a, 0x84, 0x8d, 0xfe, 0x68, 0xd5, 0x0e, 0x5c, 0x8f, 0x65, 0xa5, 0x4e,
+    0x45, 0x84, 0xa8, 0x94
+};
+
+/* HMAC SHA-256 PR  */
+__fips_constseg static const unsigned char hmac_sha256_pr_entropyinput[] = {
+    0x4d, 0xb0, 0x43, 0xd8, 0x34, 0x4b, 0x10, 0x70, 0xb1, 0x8b, 0xed, 0xea,
+    0x07, 0x92, 0x9f, 0x6c, 0x79, 0x31, 0xaf, 0x81, 0x29, 0xeb, 0x6e, 0xca,
+    0x32, 0x48, 0x28, 0xe7, 0x02, 0x5d, 0xa6, 0xa6
+};
+
+__fips_constseg static const unsigned char hmac_sha256_pr_nonce[] = {
+    0x3a, 0xae, 0x15, 0xa9, 0x99, 0xdc, 0xe4, 0x67, 0x34, 0x3b, 0x70, 0x15,
+    0xaa, 0xd3, 0x30, 0x9a
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha256_pr_personalizationstring[] = {
+    0x13, 0x1d, 0x24, 0x04, 0xb0, 0x18, 0x81, 0x15, 0x21, 0x51, 0x2a, 0x24,
+    0x52, 0x61, 0xbe, 0x64, 0x82, 0x6b, 0x55, 0x2f, 0xe2, 0xf1, 0x40, 0x7d,
+    0x71, 0xd8, 0x01, 0x86, 0x15, 0xb7, 0x8b, 0xb5
+};
+
+__fips_constseg static const unsigned char hmac_sha256_pr_additionalinput[] = {
+    0x8f, 0xa6, 0x54, 0x5f, 0xb1, 0xd0, 0xd8, 0xc3, 0xe7, 0x0c, 0x15, 0xa9,
+    0x23, 0x6e, 0xfe, 0xfb, 0x93, 0xf7, 0x3a, 0xbd, 0x59, 0x01, 0xfa, 0x18,
+    0x8e, 0xe9, 0x1a, 0xa9, 0x78, 0xfc, 0x79, 0x0b
+};
+
+__fips_constseg static const unsigned char hmac_sha256_pr_entropyinputpr[] = {
+    0xcf, 0x24, 0xb9, 0xeb, 0xb3, 0xd4, 0xcd, 0x17, 0x37, 0x38, 0x75, 0x79,
+    0x15, 0xcb, 0x2d, 0x75, 0x51, 0xf1, 0xcc, 0xaa, 0x32, 0xa4, 0xa7, 0x36,
+    0x7c, 0x5c, 0xe4, 0x47, 0xf1, 0x3e, 0x1d, 0xe5
+};
+
+__fips_constseg static const unsigned char hmac_sha256_pr_int_returnedbits[] = {
+    0x52, 0x42, 0xfa, 0xeb, 0x85, 0xe0, 0x30, 0x22, 0x79, 0x00, 0x16, 0xb2,
+    0x88, 0x2f, 0x14, 0x6a, 0xb7, 0xfc, 0xb7, 0x53, 0xdc, 0x4a, 0x12, 0xef,
+    0x54, 0xd6, 0x33, 0xe9, 0x20, 0xd6, 0xfd, 0x56
+};
+
+__fips_constseg static const unsigned char hmac_sha256_pr_additionalinput2[] = {
+    0xf4, 0xf6, 0x49, 0xa1, 0x2d, 0x64, 0x2b, 0x30, 0x58, 0xf8, 0xbd, 0xb8,
+    0x75, 0xeb, 0xbb, 0x5e, 0x1c, 0x9b, 0x81, 0x6a, 0xda, 0x14, 0x86, 0x6e,
+    0xd0, 0xda, 0x18, 0xb7, 0x88, 0xfb, 0x59, 0xf3
+};
+
+__fips_constseg static const unsigned char hmac_sha256_pr_entropyinputpr2[] = {
+    0x21, 0xcd, 0x6e, 0x46, 0xad, 0x99, 0x07, 0x17, 0xb4, 0x3d, 0x76, 0x0a,
+    0xff, 0x5b, 0x52, 0x50, 0x78, 0xdf, 0x1f, 0x24, 0x06, 0x0d, 0x3f, 0x74,
+    0xa9, 0xc9, 0x37, 0xcf, 0xd8, 0x26, 0x25, 0x91
+};
+
+__fips_constseg static const unsigned char hmac_sha256_pr_returnedbits[] = {
+    0xa7, 0xaf, 0x2f, 0x29, 0xe0, 0x3a, 0x72, 0x95, 0x96, 0x1c, 0xa9, 0xf0,
+    0x4a, 0x17, 0x4d, 0x66, 0x06, 0x10, 0xbf, 0x39, 0x89, 0x88, 0xb8, 0x91,
+    0x37, 0x18, 0x99, 0xcf, 0x8c, 0x53, 0x3b, 0x7e
+};
+
+/* HMAC SHA-256 No PR  */
+__fips_constseg static const unsigned char hmac_sha256_entropyinput[] = {
+    0x96, 0xb7, 0x53, 0x22, 0x1e, 0x52, 0x2a, 0x96, 0xb1, 0x15, 0x3c, 0x35,
+    0x5a, 0x8b, 0xd3, 0x4a, 0xa6, 0x6c, 0x83, 0x0a, 0x7d, 0xa3, 0x23, 0x3d,
+    0x43, 0xa1, 0x07, 0x2c, 0x2d, 0xe3, 0x81, 0xcc
+};
+
+__fips_constseg static const unsigned char hmac_sha256_nonce[] = {
+    0xf1, 0xac, 0x97, 0xcb, 0x5e, 0x06, 0x48, 0xd2, 0x94, 0xbe, 0x15, 0x2e,
+    0xc7, 0xfc, 0xc2, 0x01
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha256_personalizationstring[] = {
+    0x98, 0xc5, 0x1e, 0x35, 0x5e, 0x89, 0x0d, 0xce, 0x64, 0x6d, 0x18, 0xa7,
+    0x5a, 0xc6, 0xf3, 0xe7, 0xd6, 0x9e, 0xc0, 0xea, 0xb7, 0x3a, 0x8d, 0x65,
+    0xb8, 0xeb, 0x10, 0xd7, 0x57, 0x18, 0xa0, 0x32
+};
+
+__fips_constseg static const unsigned char hmac_sha256_additionalinput[] = {
+    0x1b, 0x10, 0xaf, 0xac, 0xd0, 0x65, 0x95, 0xad, 0x04, 0xad, 0x03, 0x1c,
+    0xe0, 0x40, 0xd6, 0x3e, 0x1c, 0x46, 0x53, 0x39, 0x7c, 0xe2, 0xbc, 0xda,
+    0x8c, 0xa2, 0x33, 0xa7, 0x9a, 0x26, 0xd3, 0x27
+};
+
+__fips_constseg static const unsigned char hmac_sha256_int_returnedbits[] = {
+    0xba, 0x61, 0x0e, 0x55, 0xfe, 0x11, 0x8a, 0x9e, 0x0f, 0x80, 0xdf, 0x1d,
+    0x03, 0x0a, 0xfe, 0x15, 0x94, 0x28, 0x4b, 0xba, 0xf4, 0x9f, 0x51, 0x25,
+    0x88, 0xe5, 0x4e, 0xfb, 0xaf, 0xce, 0x69, 0x90
+};
+
+__fips_constseg static const unsigned char hmac_sha256_entropyinputreseed[] = {
+    0x62, 0x7f, 0x1e, 0x6b, 0xe8, 0x8e, 0xe1, 0x35, 0x7d, 0x9b, 0x4f, 0xc7,
+    0xec, 0xc8, 0xac, 0xef, 0x6b, 0x13, 0x9e, 0x05, 0x56, 0xc1, 0x08, 0xf9,
+    0x2f, 0x0f, 0x27, 0x9c, 0xd4, 0x15, 0xed, 0x2d
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha256_additionalinputreseed[] = {
+    0xc7, 0x76, 0x6e, 0xa9, 0xd2, 0xb2, 0x76, 0x40, 0x82, 0x25, 0x2c, 0xb3,
+    0x6f, 0xac, 0xe9, 0x74, 0xef, 0x8f, 0x3c, 0x8e, 0xcd, 0xf1, 0xbf, 0xb3,
+    0x49, 0x77, 0x34, 0x88, 0x52, 0x36, 0xe6, 0x2e
+};
+
+__fips_constseg static const unsigned char hmac_sha256_additionalinput2[] = {
+    0x8d, 0xb8, 0x0c, 0xd1, 0xbf, 0x70, 0xf6, 0x19, 0xc3, 0x41, 0x80, 0x9f,
+    0xe1, 0xa5, 0xa4, 0x1f, 0x2c, 0x26, 0xb1, 0xe5, 0xd8, 0xeb, 0xbe, 0xf8,
+    0xdf, 0x88, 0x6a, 0x89, 0xd6, 0x05, 0xd8, 0x9d
+};
+
+__fips_constseg static const unsigned char hmac_sha256_returnedbits[] = {
+    0x43, 0x12, 0x2a, 0x2c, 0x40, 0x53, 0x2e, 0x7c, 0x66, 0x34, 0xac, 0xc3,
+    0x43, 0xe3, 0xe0, 0x6a, 0xfc, 0xfa, 0xea, 0x87, 0x21, 0x1f, 0xe2, 0x26,
+    0xc4, 0xf9, 0x09, 0x9a, 0x0d, 0x6e, 0x7f, 0xe0
+};
+
+/* HMAC SHA-384 PR  */
+__fips_constseg static const unsigned char hmac_sha384_pr_entropyinput[] = {
+    0x69, 0x81, 0x98, 0x88, 0x44, 0xf5, 0xd6, 0x2e, 0x00, 0x08, 0x3b, 0xc5,
+    0xfb, 0xd7, 0x8e, 0x6f, 0x23, 0xf8, 0x6d, 0x09, 0xd6, 0x85, 0x49, 0xd1,
+    0xf8, 0x6d, 0xa4, 0x58, 0x54, 0xfd, 0x88, 0xa9
+};
+
+__fips_constseg static const unsigned char hmac_sha384_pr_nonce[] = {
+    0x6e, 0x38, 0x81, 0xca, 0xb7, 0xe8, 0x6e, 0x66, 0x49, 0x8a, 0xb2, 0x59,
+    0xee, 0x16, 0xc9, 0xde
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha384_pr_personalizationstring[] = {
+    0xfe, 0x4c, 0xd9, 0xf4, 0x78, 0x3b, 0x08, 0x41, 0x8d, 0x8f, 0x55, 0xc4,
+    0x43, 0x56, 0xb6, 0x12, 0x36, 0x6b, 0x30, 0xb7, 0x5e, 0xe1, 0xb9, 0x47,
+    0x04, 0xb1, 0x4e, 0xa9, 0x00, 0xa1, 0x52, 0xa1
+};
+
+__fips_constseg static const unsigned char hmac_sha384_pr_additionalinput[] = {
+    0x89, 0xe9, 0xcc, 0x8f, 0x27, 0x3c, 0x26, 0xd1, 0x95, 0xc8, 0x7d, 0x0f,
+    0x5b, 0x1a, 0xf0, 0x78, 0x39, 0x56, 0x6f, 0xa4, 0x23, 0xe7, 0xd1, 0xda,
+    0x7c, 0x66, 0x33, 0xa0, 0x90, 0xc9, 0x92, 0x88
+};
+
+__fips_constseg static const unsigned char hmac_sha384_pr_entropyinputpr[] = {
+    0xbe, 0x3d, 0x7c, 0x0d, 0xca, 0xda, 0x7c, 0x49, 0xb8, 0x12, 0x36, 0xc0,
+    0xdb, 0xad, 0x35, 0xa8, 0xc7, 0x0b, 0x2a, 0x2c, 0x69, 0x6d, 0x25, 0x56,
+    0x63, 0x82, 0x11, 0x3e, 0xa7, 0x33, 0x70, 0x72
+};
+
+__fips_constseg static const unsigned char hmac_sha384_pr_int_returnedbits[] = {
+    0x82, 0x3d, 0xe6, 0x54, 0x80, 0x42, 0xf8, 0xba, 0x90, 0x4f, 0x06, 0xa6,
+    0xd2, 0x7f, 0xbf, 0x79, 0x7c, 0x12, 0x7d, 0xa6, 0xa2, 0x66, 0xe8, 0xa6,
+    0xc0, 0xd6, 0x4a, 0x55, 0xbf, 0xd8, 0x0a, 0xc5, 0xf8, 0x03, 0x88, 0xdd,
+    0x8e, 0x87, 0xd1, 0x5a, 0x48, 0x26, 0x72, 0x2a, 0x8e, 0xcf, 0xee, 0xba
+};
+
+__fips_constseg static const unsigned char hmac_sha384_pr_additionalinput2[] = {
+    0x8f, 0xff, 0xd9, 0x84, 0xbb, 0x85, 0x3a, 0x66, 0xa1, 0x21, 0xce, 0xb2,
+    0x3a, 0x3a, 0x17, 0x22, 0x19, 0xae, 0xc7, 0xb6, 0x63, 0x81, 0xd5, 0xff,
+    0x0d, 0xc8, 0xe1, 0xaf, 0x57, 0xd2, 0xcb, 0x60
+};
+
+__fips_constseg static const unsigned char hmac_sha384_pr_entropyinputpr2[] = {
+    0xd7, 0xfb, 0xc9, 0xe8, 0xe2, 0xf2, 0xaa, 0x4c, 0xb8, 0x51, 0x2f, 0xe1,
+    0x22, 0xba, 0xf3, 0xda, 0x0a, 0x19, 0x76, 0x71, 0x57, 0xb2, 0x1d, 0x94,
+    0x09, 0x69, 0x6c, 0xd3, 0x97, 0x51, 0x81, 0x87
+};
+
+__fips_constseg static const unsigned char hmac_sha384_pr_returnedbits[] = {
+    0xe6, 0x19, 0x28, 0xa8, 0x21, 0xce, 0x5e, 0xdb, 0x24, 0x79, 0x8c, 0x76,
+    0x5d, 0x73, 0xb2, 0xdf, 0xac, 0xef, 0x85, 0xa7, 0x3b, 0x19, 0x09, 0x8b,
+    0x7f, 0x98, 0x28, 0xa9, 0x93, 0xd8, 0x7a, 0xad, 0x55, 0x8b, 0x24, 0x9d,
+    0xe6, 0x98, 0xfe, 0x47, 0xd5, 0x48, 0xc1, 0x23, 0xd8, 0x1d, 0x62, 0x75
+};
+
+/* HMAC SHA-384 No PR  */
+__fips_constseg static const unsigned char hmac_sha384_entropyinput[] = {
+    0xc3, 0x56, 0x2b, 0x1d, 0xc2, 0xbb, 0xa8, 0xf0, 0xae, 0x1b, 0x0d, 0xd3,
+    0x5a, 0x6c, 0xda, 0x57, 0x8e, 0xa5, 0x8a, 0x0d, 0x6c, 0x4b, 0x18, 0xb1,
+    0x04, 0x3e, 0xb4, 0x99, 0x35, 0xc4, 0xc0, 0x5f
+};
+
+__fips_constseg static const unsigned char hmac_sha384_nonce[] = {
+    0xc5, 0x49, 0x1e, 0x66, 0x27, 0x92, 0xbe, 0xec, 0xb5, 0x1e, 0x4b, 0xb1,
+    0x38, 0xe3, 0xeb, 0x62
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha384_personalizationstring[] = {
+    0xbe, 0xe7, 0x6b, 0x57, 0xde, 0x88, 0x11, 0x96, 0x9b, 0x6e, 0xea, 0xe5,
+    0x63, 0x83, 0x4c, 0xb6, 0x8d, 0x66, 0xaa, 0x1f, 0x8b, 0x54, 0xe7, 0x62,
+    0x6d, 0x5a, 0xfc, 0xbf, 0x97, 0xba, 0xcd, 0x77
+};
+
+__fips_constseg static const unsigned char hmac_sha384_additionalinput[] = {
+    0xe5, 0x28, 0x5f, 0x43, 0xf5, 0x83, 0x6e, 0x0a, 0x83, 0x5c, 0xe3, 0x81,
+    0x03, 0xf2, 0xf8, 0x78, 0x00, 0x7c, 0x95, 0x87, 0x16, 0xd6, 0x6c, 0x58,
+    0x33, 0x6c, 0x53, 0x35, 0x0d, 0x66, 0xe3, 0xce
+};
+
+__fips_constseg static const unsigned char hmac_sha384_int_returnedbits[] = {
+    0xe2, 0x1f, 0xf3, 0xda, 0x0d, 0x19, 0x99, 0x87, 0xc4, 0x90, 0xa2, 0x31,
+    0xca, 0x2a, 0x89, 0x58, 0x43, 0x44, 0xb8, 0xde, 0xcf, 0xa4, 0xbe, 0x3b,
+    0x53, 0x26, 0x22, 0x31, 0x76, 0x41, 0x22, 0xb5, 0xa8, 0x70, 0x2f, 0x4b,
+    0x64, 0x95, 0x4d, 0x48, 0x96, 0x35, 0xe6, 0xbd, 0x3c, 0x34, 0xdb, 0x1b
+};
+
+__fips_constseg static const unsigned char hmac_sha384_entropyinputreseed[] = {
+    0x77, 0x61, 0xba, 0xbc, 0xf2, 0xc1, 0xf3, 0x4b, 0x86, 0x65, 0xfd, 0x48,
+    0x0e, 0x3c, 0x02, 0x5e, 0xa2, 0x7a, 0x6b, 0x7c, 0xed, 0x21, 0x5e, 0xf9,
+    0xcd, 0xcd, 0x77, 0x07, 0x2b, 0xbe, 0xc5, 0x5c
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha384_additionalinputreseed[] = {
+    0x18, 0x24, 0x5f, 0xc6, 0x84, 0xd1, 0x67, 0xc3, 0x9a, 0x11, 0xa5, 0x8c,
+    0x07, 0x39, 0x21, 0x83, 0x4d, 0x04, 0xc4, 0x6a, 0x28, 0x19, 0xcf, 0x92,
+    0x21, 0xd9, 0x9e, 0x41, 0x72, 0x6c, 0x9e, 0x63
+};
+
+__fips_constseg static const unsigned char hmac_sha384_additionalinput2[] = {
+    0x96, 0x67, 0x41, 0x28, 0x9b, 0xb7, 0x92, 0x8d, 0x64, 0x3b, 0xe4, 0xcf,
+    0x7e, 0xaa, 0x1e, 0xb1, 0x4b, 0x1d, 0x09, 0x56, 0x67, 0x9c, 0xc6, 0x6d,
+    0x3b, 0xe8, 0x91, 0x9d, 0xe1, 0x8a, 0xb7, 0x32
+};
+
+__fips_constseg static const unsigned char hmac_sha384_returnedbits[] = {
+    0xe3, 0x59, 0x61, 0x38, 0x92, 0xec, 0xe2, 0x3c, 0xff, 0xb7, 0xdb, 0x19,
+    0x0f, 0x5b, 0x93, 0x68, 0x0d, 0xa4, 0x94, 0x40, 0x72, 0x0b, 0xe0, 0xed,
+    0x4d, 0xcd, 0x68, 0xa0, 0x1e, 0xfe, 0x67, 0xb2, 0xfa, 0x21, 0x56, 0x74,
+    0xa4, 0xad, 0xcf, 0xb7, 0x60, 0x66, 0x2e, 0x40, 0xde, 0x82, 0xca, 0xfb
+};
+
+/* HMAC SHA-512 PR  */
+__fips_constseg static const unsigned char hmac_sha512_pr_entropyinput[] = {
+    0xaa, 0x9e, 0x45, 0x67, 0x0e, 0x00, 0x2a, 0x67, 0x98, 0xd6, 0xda, 0x0b,
+    0x0f, 0x17, 0x7e, 0xac, 0xfd, 0x27, 0xc4, 0xca, 0x84, 0xdf, 0xde, 0xba,
+    0x85, 0xd9, 0xbe, 0x8f, 0xf3, 0xff, 0x91, 0x4d
+};
+
+__fips_constseg static const unsigned char hmac_sha512_pr_nonce[] = {
+    0x8c, 0x49, 0x2f, 0x58, 0x1e, 0x7a, 0xda, 0x4b, 0x7e, 0x8a, 0x30, 0x7b,
+    0x86, 0xea, 0xaf, 0xa2
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha512_pr_personalizationstring[] = {
+    0x71, 0xe1, 0xbb, 0xad, 0xa7, 0x4b, 0x2e, 0x31, 0x3b, 0x0b, 0xec, 0x24,
+    0x99, 0x38, 0xbc, 0xaa, 0x05, 0x4c, 0x46, 0x44, 0xfa, 0xad, 0x8e, 0x02,
+    0xc1, 0x7e, 0xad, 0xec, 0x54, 0xa6, 0xd0, 0xad
+};
+
+__fips_constseg static const unsigned char hmac_sha512_pr_additionalinput[] = {
+    0x3d, 0x6e, 0xa6, 0xa8, 0x29, 0x2a, 0xb2, 0xf5, 0x98, 0x42, 0xe4, 0x92,
+    0x78, 0x22, 0x67, 0xfd, 0x1b, 0x15, 0x1e, 0x29, 0xaa, 0x71, 0x3c, 0x3c,
+    0xe7, 0x05, 0x20, 0xa9, 0x29, 0xc6, 0x75, 0x71
+};
+
+__fips_constseg static const unsigned char hmac_sha512_pr_entropyinputpr[] = {
+    0xab, 0xb9, 0x16, 0xd8, 0x55, 0x35, 0x54, 0xb7, 0x97, 0x3f, 0x94, 0xbc,
+    0x2f, 0x7c, 0x70, 0xc7, 0xd0, 0xed, 0xb7, 0x4b, 0xf7, 0xf6, 0x6c, 0x03,
+    0x0c, 0xb0, 0x03, 0xd8, 0xbb, 0x71, 0xd9, 0x10
+};
+
+__fips_constseg static const unsigned char hmac_sha512_pr_int_returnedbits[] = {
+    0x8e, 0xd3, 0xfd, 0x52, 0x9e, 0x83, 0x08, 0x49, 0x18, 0x6e, 0x23, 0x56,
+    0x5c, 0x45, 0x93, 0x34, 0x05, 0xe2, 0x98, 0x8f, 0x0c, 0xd4, 0x32, 0x0c,
+    0xfd, 0xda, 0x5f, 0x92, 0x3a, 0x8c, 0x81, 0xbd, 0xf6, 0x6c, 0x55, 0xfd,
+    0xb8, 0x20, 0xce, 0x8d, 0x97, 0x27, 0xe8, 0xe8, 0xe0, 0xb3, 0x85, 0x50,
+    0xa2, 0xc2, 0xb2, 0x95, 0x1d, 0x48, 0xd3, 0x7b, 0x4b, 0x78, 0x13, 0x35,
+    0x05, 0x17, 0xbe, 0x0d
+};
+
+__fips_constseg static const unsigned char hmac_sha512_pr_additionalinput2[] = {
+    0xc3, 0xfc, 0x95, 0xaa, 0x69, 0x06, 0xae, 0x59, 0x41, 0xce, 0x26, 0x08,
+    0x29, 0x6d, 0x45, 0xda, 0xe8, 0xb3, 0x6c, 0x95, 0x60, 0x0f, 0x70, 0x2c,
+    0x10, 0xba, 0x38, 0x8c, 0xcf, 0x29, 0x99, 0xaa
+};
+
+__fips_constseg static const unsigned char hmac_sha512_pr_entropyinputpr2[] = {
+    0x3b, 0x9a, 0x25, 0xce, 0xd7, 0xf9, 0x5c, 0xd1, 0x3a, 0x3e, 0xaa, 0x71,
+    0x14, 0x3e, 0x19, 0xe8, 0xce, 0xe6, 0xfe, 0x51, 0x84, 0xe9, 0x1b, 0xfe,
+    0x3f, 0xa7, 0xf2, 0xfd, 0x76, 0x5f, 0x6a, 0xe7
+};
+
+__fips_constseg static const unsigned char hmac_sha512_pr_returnedbits[] = {
+    0xb7, 0x82, 0xa9, 0x57, 0x81, 0x67, 0x53, 0xb5, 0xa1, 0xe9, 0x3d, 0x35,
+    0xf9, 0xe4, 0x97, 0xbe, 0xa6, 0xca, 0xf1, 0x01, 0x13, 0x09, 0xe7, 0x21,
+    0xc0, 0xed, 0x93, 0x5d, 0x4b, 0xf4, 0xeb, 0x8d, 0x53, 0x25, 0x8a, 0xc4,
+    0xb1, 0x6f, 0x6e, 0x37, 0xcd, 0x2e, 0xac, 0x39, 0xb2, 0xb6, 0x99, 0xa3,
+    0x82, 0x00, 0xb0, 0x21, 0xf0, 0xc7, 0x2f, 0x4c, 0x73, 0x92, 0xfd, 0x00,
+    0xb6, 0xaf, 0xbc, 0xd3
+};
+
+/* HMAC SHA-512 No PR  */
+__fips_constseg static const unsigned char hmac_sha512_entropyinput[] = {
+    0x6e, 0x85, 0xe6, 0x25, 0x96, 0x29, 0xa7, 0x52, 0x5b, 0x60, 0xba, 0xaa,
+    0xde, 0xdb, 0x36, 0x0a, 0x51, 0x9a, 0x15, 0xae, 0x6e, 0x18, 0xd3, 0xfe,
+    0x39, 0xb9, 0x4a, 0x96, 0xf8, 0x77, 0xcb, 0x95
+};
+
+__fips_constseg static const unsigned char hmac_sha512_nonce[] = {
+    0xe0, 0xa6, 0x5d, 0x08, 0xc3, 0x7c, 0xae, 0x25, 0x2e, 0x80, 0xd1, 0x3e,
+    0xd9, 0xaf, 0x43, 0x3c
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha512_personalizationstring[] = {
+    0x53, 0x99, 0x52, 0x5f, 0x11, 0xa9, 0x64, 0x66, 0x20, 0x5e, 0x1b, 0x5f,
+    0x42, 0xb3, 0xf4, 0xda, 0xed, 0xbb, 0x63, 0xc1, 0x23, 0xaf, 0xd0, 0x01,
+    0x90, 0x3b, 0xd0, 0x78, 0xe4, 0x0b, 0xa7, 0x20
+};
+
+__fips_constseg static const unsigned char hmac_sha512_additionalinput[] = {
+    0x85, 0x90, 0x80, 0xd3, 0x98, 0xf1, 0x53, 0x6d, 0x68, 0x15, 0x8f, 0xe5,
+    0x60, 0x3f, 0x17, 0x29, 0x55, 0x8d, 0x33, 0xb1, 0x45, 0x64, 0x64, 0x8d,
+    0x50, 0x21, 0x89, 0xae, 0xf6, 0xfd, 0x32, 0x73
+};
+
+__fips_constseg static const unsigned char hmac_sha512_int_returnedbits[] = {
+    0x28, 0x56, 0x30, 0x6f, 0xf4, 0xa1, 0x48, 0xe0, 0xc9, 0xf5, 0x75, 0x90,
+    0xcc, 0xfb, 0xdf, 0xdf, 0x71, 0x3d, 0x0a, 0x9a, 0x03, 0x65, 0x3b, 0x18,
+    0x61, 0xe3, 0xd1, 0xda, 0xcc, 0x4a, 0xfe, 0x55, 0x38, 0xf8, 0x21, 0x6b,
+    0xfa, 0x18, 0x01, 0x42, 0x39, 0x2f, 0x99, 0x53, 0x38, 0x15, 0x82, 0x34,
+    0xc5, 0x93, 0x92, 0xbc, 0x4d, 0x75, 0x1a, 0x5f, 0x21, 0x27, 0xcc, 0xa1,
+    0xb1, 0x57, 0x69, 0xe8
+};
+
+__fips_constseg static const unsigned char hmac_sha512_entropyinputreseed[] = {
+    0x8c, 0x52, 0x7e, 0x77, 0x72, 0x3f, 0xa3, 0x04, 0x97, 0x10, 0x9b, 0x41,
+    0xbd, 0xe8, 0xff, 0x89, 0xed, 0x80, 0xe3, 0xbd, 0xaa, 0x12, 0x2d, 0xca,
+    0x75, 0x82, 0x36, 0x77, 0x88, 0xcd, 0xa6, 0x73
+};
+
+__fips_constseg
+    static const unsigned char hmac_sha512_additionalinputreseed[] = {
+    0x7e, 0x32, 0xe3, 0x69, 0x69, 0x07, 0x34, 0xa2, 0x16, 0xa2, 0x5d, 0x1a,
+    0x10, 0x91, 0xd3, 0xe2, 0x21, 0xa2, 0xa3, 0xdd, 0xcd, 0x0c, 0x09, 0x86,
+    0x11, 0xe1, 0x50, 0xff, 0x5c, 0xb7, 0xeb, 0x5c
+};
+
+__fips_constseg static const unsigned char hmac_sha512_additionalinput2[] = {
+    0x7f, 0x78, 0x66, 0xd8, 0xfb, 0x67, 0xcf, 0x8d, 0x8c, 0x08, 0x30, 0xa5,
+    0xf8, 0x7d, 0xcf, 0x44, 0x59, 0xce, 0xf8, 0xdf, 0x58, 0xd3, 0x60, 0xcb,
+    0xa8, 0x60, 0xb9, 0x07, 0xc4, 0xb1, 0x95, 0x48
+};
+
+__fips_constseg static const unsigned char hmac_sha512_returnedbits[] = {
+    0xdf, 0xa7, 0x36, 0xd4, 0xdc, 0x5d, 0x4d, 0x31, 0xad, 0x69, 0x46, 0x9f,
+    0xf1, 0x7c, 0xd7, 0x3b, 0x4f, 0x55, 0xf2, 0xd7, 0xb9, 0x9d, 0xad, 0x7a,
+    0x79, 0x08, 0x59, 0xa5, 0xdc, 0x74, 0xf5, 0x9b, 0x73, 0xd2, 0x13, 0x25,
+    0x0b, 0x81, 0x08, 0x08, 0x25, 0xfb, 0x39, 0xf2, 0xf0, 0xa3, 0xa4, 0x8d,
+    0xef, 0x05, 0x9e, 0xb8, 0xc7, 0x52, 0xe4, 0x0e, 0x42, 0xaa, 0x7c, 0x79,
+    0xc2, 0xd6, 0xfd, 0xa5
+};
diff -up openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c.fips	2016-09-22 13:35:57.016220974 +0200
+++ openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c	2016-09-22 13:35:57.016220974 +0200
@@ -0,0 +1,192 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+static const unsigned char dsa_test_2048_p[] = {
+    0xa8, 0x53, 0x78, 0xd8, 0xfd, 0x3f, 0x8d, 0x72, 0xec, 0x74, 0x18, 0x08,
+    0x0d, 0xa2, 0x13, 0x17, 0xe4, 0x3e, 0xc4, 0xb6, 0x2b, 0xa8, 0xc8, 0x62,
+    0x3b, 0x7e, 0x4d, 0x04, 0x44, 0x1d, 0xd1, 0xa0, 0x65, 0x86, 0x62, 0x59,
+    0x64, 0x93, 0xca, 0x8e, 0x9e, 0x8f, 0xbb, 0x7e, 0x34, 0xaa, 0xdd, 0xb6,
+    0x2e, 0x5d, 0x67, 0xb6, 0xd0, 0x9a, 0x6e, 0x61, 0xb7, 0x69, 0xe7, 0xc3,
+    0x52, 0xaa, 0x2b, 0x10, 0xe2, 0x0c, 0xa0, 0x63, 0x69, 0x63, 0xb5, 0x52,
+    0x3e, 0x86, 0x47, 0x0d, 0xec, 0xbb, 0xed, 0xa0, 0x27, 0xe7, 0x97, 0xe7,
+    0xb6, 0x76, 0x35, 0xd4, 0xd4, 0x9c, 0x30, 0x70, 0x0e, 0x74, 0xaf, 0x8a,
+    0x0f, 0xf1, 0x56, 0xa8, 0x01, 0xaf, 0x57, 0xa2, 0x6e, 0x70, 0x78, 0xf1,
+    0xd8, 0x2f, 0x74, 0x90, 0x8e, 0xcb, 0x6d, 0x07, 0xe7, 0x0b, 0x35, 0x03,
+    0xee, 0xd9, 0x4f, 0xa3, 0x2c, 0xf1, 0x7a, 0x7f, 0xc3, 0xd6, 0xcf, 0x40,
+    0xdc, 0x7b, 0x00, 0x83, 0x0e, 0x6a, 0x25, 0x66, 0xdc, 0x07, 0x3e, 0x34,
+    0x33, 0x12, 0x51, 0x7c, 0x6a, 0xa5, 0x15, 0x2b, 0x4b, 0xfe, 0xcd, 0x2e,
+    0x55, 0x1f, 0xee, 0x34, 0x63, 0x18, 0xa1, 0x53, 0x42, 0x3c, 0x99, 0x6b,
+    0x0d, 0x5d, 0xcb, 0x91, 0x02, 0xae, 0xdd, 0x38, 0x79, 0x86, 0x16, 0xf1,
+    0xf1, 0xe0, 0xd6, 0xc4, 0x03, 0x52, 0x5b, 0x1f, 0x9b, 0x3d, 0x4d, 0xc7,
+    0x66, 0xde, 0x2d, 0xfc, 0x4a, 0x56, 0xd7, 0xb8, 0xba, 0x59, 0x63, 0xd6,
+    0x0f, 0x3e, 0x16, 0x31, 0x88, 0x70, 0xad, 0x43, 0x69, 0x52, 0xe5, 0x57,
+    0x65, 0x37, 0x4e, 0xab, 0x85, 0xe8, 0xec, 0x17, 0xd6, 0xb9, 0xa4, 0x54,
+    0x7b, 0x9b, 0x5f, 0x27, 0x52, 0xf3, 0x10, 0x5b, 0xe8, 0x09, 0xb2, 0x3a,
+    0x2c, 0x8d, 0x74, 0x69, 0xdb, 0x02, 0xe2, 0x4d, 0x59, 0x23, 0x94, 0xa7,
+    0xdb, 0xa0, 0x69, 0xe9
+};
+
+static const unsigned char dsa_test_2048_q[] = {
+    0xd2, 0x77, 0x04, 0x4e, 0x50, 0xf5, 0xa4, 0xe3, 0xf5, 0x10, 0xa5, 0x0a,
+    0x0b, 0x84, 0xfd, 0xff, 0xbc, 0xa0, 0x47, 0xed, 0x27, 0x60, 0x20, 0x56,
+    0x74, 0x41, 0xa0, 0xa5
+};
+
+static const unsigned char dsa_test_2048_g[] = {
+    0x13, 0xd7, 0x54, 0xe2, 0x1f, 0xd2, 0x41, 0x65, 0x5d, 0xa8, 0x91, 0xc5,
+    0x22, 0xa6, 0x5a, 0x72, 0xa8, 0x9b, 0xdc, 0x64, 0xec, 0x9b, 0x54, 0xa8,
+    0x21, 0xed, 0x4a, 0x89, 0x8b, 0x49, 0x0e, 0x0c, 0x4f, 0xcb, 0x72, 0x19,
+    0x2a, 0x4a, 0x20, 0xf5, 0x41, 0xf3, 0xf2, 0x92, 0x53, 0x99, 0xf0, 0xba,
+    0xec, 0xf9, 0x29, 0xaa, 0xfb, 0xf7, 0x9d, 0xfe, 0x43, 0x32, 0x39, 0x3b,
+    0x32, 0xcd, 0x2e, 0x2f, 0xcf, 0x27, 0x2f, 0x32, 0xa6, 0x27, 0x43, 0x4a,
+    0x0d, 0xf2, 0x42, 0xb7, 0x5b, 0x41, 0x4d, 0xf3, 0x72, 0x12, 0x1e, 0x53,
+    0xa5, 0x53, 0xf2, 0x22, 0xf8, 0x36, 0xb0, 0x00, 0xf0, 0x16, 0x48, 0x5b,
+    0x6b, 0xd0, 0x89, 0x84, 0x51, 0x80, 0x1d, 0xcd, 0x8d, 0xe6, 0x4c, 0xd5,
+    0x36, 0x56, 0x96, 0xff, 0xc5, 0x32, 0xd5, 0x28, 0xc5, 0x06, 0x62, 0x0a,
+    0x94, 0x2a, 0x03, 0x05, 0x04, 0x6d, 0x8f, 0x18, 0x76, 0x34, 0x1f, 0x1e,
+    0x57, 0x0b, 0xc3, 0x97, 0x4b, 0xa6, 0xb9, 0xa4, 0x38, 0xe9, 0x70, 0x23,
+    0x02, 0xa2, 0xe6, 0xe6, 0x7b, 0xfd, 0x06, 0xd3, 0x2b, 0xc6, 0x79, 0x96,
+    0x22, 0x71, 0xd7, 0xb4, 0x0c, 0xd7, 0x2f, 0x38, 0x6e, 0x64, 0xe0, 0xd7,
+    0xef, 0x86, 0xca, 0x8c, 0xa5, 0xd1, 0x42, 0x28, 0xdc, 0x2a, 0x4f, 0x16,
+    0xe3, 0x18, 0x98, 0x86, 0xb5, 0x99, 0x06, 0x74, 0xf4, 0x20, 0x0f, 0x3a,
+    0x4c, 0xf6, 0x5a, 0x3f, 0x0d, 0xdb, 0xa1, 0xfa, 0x67, 0x2d, 0xff, 0x2f,
+    0x5e, 0x14, 0x3d, 0x10, 0xe4, 0xe9, 0x7a, 0xe8, 0x4f, 0x6d, 0xa0, 0x95,
+    0x35, 0xd5, 0xb9, 0xdf, 0x25, 0x91, 0x81, 0xa7, 0x9b, 0x63, 0xb0, 0x69,
+    0xe9, 0x49, 0x97, 0x2b, 0x02, 0xba, 0x36, 0xb3, 0x58, 0x6a, 0xab, 0x7e,
+    0x45, 0xf3, 0x22, 0xf8, 0x2e, 0x4e, 0x85, 0xca, 0x3a, 0xb8, 0x55, 0x91,
+    0xb3, 0xc2, 0xa9, 0x66
+};
+
+static const unsigned char dsa_test_2048_pub_key[] = {
+    0x24, 0x52, 0xf3, 0xcc, 0xbe, 0x9e, 0xd5, 0xca, 0x7d, 0xc7, 0x4c, 0x60,
+    0x2b, 0x99, 0x22, 0x6e, 0x8f, 0x2f, 0xab, 0x38, 0xe7, 0xd7, 0xdd, 0xfb,
+    0x75, 0x53, 0x9b, 0x17, 0x15, 0x5e, 0x9f, 0xcf, 0xd1, 0xab, 0xa5, 0x64,
+    0xeb, 0x85, 0x35, 0xd8, 0x12, 0xc9, 0xc2, 0xdc, 0xf9, 0x72, 0x84, 0x44,
+    0x1b, 0xc4, 0x82, 0x24, 0x36, 0x24, 0xc7, 0xf4, 0x57, 0x58, 0x0c, 0x1c,
+    0x38, 0xa5, 0x7c, 0x46, 0xc4, 0x57, 0x39, 0x24, 0x70, 0xed, 0xb5, 0x2c,
+    0xb5, 0xa6, 0xe0, 0x3f, 0xe6, 0x28, 0x7b, 0xb6, 0xf4, 0x9a, 0x42, 0xa2,
+    0x06, 0x5a, 0x05, 0x4f, 0x03, 0x08, 0x39, 0xdf, 0x1f, 0xd3, 0x14, 0x9c,
+    0x4c, 0xa0, 0x53, 0x1d, 0xd8, 0xca, 0x8a, 0xaa, 0x9c, 0xc7, 0x33, 0x71,
+    0x93, 0x38, 0x73, 0x48, 0x33, 0x61, 0x18, 0x22, 0x45, 0x45, 0xe8, 0x8c,
+    0x80, 0xff, 0xd8, 0x76, 0x5d, 0x74, 0x36, 0x03, 0x33, 0xcc, 0xab, 0x99,
+    0x72, 0x77, 0x9b, 0x65, 0x25, 0xa6, 0x5b, 0xdd, 0x0d, 0x10, 0xc6, 0x75,
+    0xc1, 0x09, 0xbb, 0xd3, 0xe5, 0xbe, 0x4d, 0x72, 0xef, 0x6e, 0xba, 0x6e,
+    0x43, 0x8d, 0x52, 0x26, 0x23, 0x7d, 0xb8, 0x88, 0x37, 0x9c, 0x5f, 0xcc,
+    0x47, 0xa3, 0x84, 0x7f, 0xf6, 0x37, 0x11, 0xba, 0xed, 0x6d, 0x03, 0xaf,
+    0xe8, 0x1e, 0x69, 0x4a, 0x41, 0x3b, 0x68, 0x0b, 0xd3, 0x8a, 0xb4, 0x90,
+    0x3f, 0x83, 0x70, 0xa7, 0x07, 0xef, 0x55, 0x1d, 0x49, 0x41, 0x02, 0x6d,
+    0x95, 0x79, 0xd6, 0x91, 0xde, 0x8e, 0xda, 0xa1, 0x61, 0x05, 0xeb, 0x9d,
+    0xba, 0x3c, 0x2f, 0x4c, 0x1b, 0xec, 0x50, 0x82, 0x75, 0xaa, 0x02, 0x07,
+    0xe2, 0x51, 0xb5, 0xec, 0xcb, 0x28, 0x6a, 0x4b, 0x01, 0xd4, 0x49, 0xd3,
+    0x0a, 0xcb, 0x67, 0x37, 0x17, 0xa0, 0xd2, 0xfb, 0x3b, 0x50, 0xc8, 0x93,
+    0xf7, 0xda, 0xb1, 0x4f
+};
+
+static const unsigned char dsa_test_2048_priv_key[] = {
+    0x0c, 0x4b, 0x30, 0x89, 0xd1, 0xb8, 0x62, 0xcb, 0x3c, 0x43, 0x64, 0x91,
+    0xf0, 0x91, 0x54, 0x70, 0xc5, 0x27, 0x96, 0xe3, 0xac, 0xbe, 0xe8, 0x00,
+    0xec, 0x55, 0xf6, 0xcc
+};
+
+static int corrupt_dsa;
+
+void FIPS_corrupt_dsa()
+{
+    corrupt_dsa = 1;
+}
+
+int FIPS_selftest_dsa()
+{
+    DSA *dsa = NULL;
+    EVP_PKEY *pk = NULL;
+    int ret = 0;
+
+    dsa = DSA_new();
+
+    if (dsa == NULL)
+        goto err;
+
+    fips_load_key_component(dsa, p, dsa_test_2048);
+    fips_load_key_component(dsa, q, dsa_test_2048);
+    fips_load_key_component(dsa, g, dsa_test_2048);
+    fips_load_key_component(dsa, pub_key, dsa_test_2048);
+    fips_load_key_component(dsa, priv_key, dsa_test_2048);
+
+    if (corrupt_dsa)
+        BN_set_bit(dsa->pub_key, 2047);
+
+    if ((pk = EVP_PKEY_new()) == NULL)
+        goto err;
+
+    EVP_PKEY_assign_DSA(pk, dsa);
+
+    if (!fips_pkey_signature_test(pk, NULL, 0,
+                                  NULL, 0, EVP_sha256(), 0, "DSA SHA256"))
+        goto err;
+    ret = 1;
+
+ err:
+    if (pk)
+        EVP_PKEY_free(pk);
+    else if (dsa)
+        DSA_free(dsa);
+    return ret;
+}
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_enc.c.fips openssl-1.0.2i/crypto/fips/fips_enc.c
--- openssl-1.0.2i/crypto/fips/fips_enc.c.fips	2016-09-22 13:35:57.017220997 +0200
+++ openssl-1.0.2i/crypto/fips/fips_enc.c	2016-09-22 13:35:57.017220997 +0200
@@ -0,0 +1,189 @@
+/* fipe/evp/fips_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+const EVP_CIPHER *FIPS_get_cipherbynid(int nid)
+{
+    switch (nid) {
+    case NID_aes_128_cbc:
+        return EVP_aes_128_cbc();
+
+    case NID_aes_128_ccm:
+        return EVP_aes_128_ccm();
+
+    case NID_aes_128_cfb1:
+        return EVP_aes_128_cfb1();
+
+    case NID_aes_128_cfb128:
+        return EVP_aes_128_cfb128();
+
+    case NID_aes_128_cfb8:
+        return EVP_aes_128_cfb8();
+
+    case NID_aes_128_ctr:
+        return EVP_aes_128_ctr();
+
+    case NID_aes_128_ecb:
+        return EVP_aes_128_ecb();
+
+    case NID_aes_128_gcm:
+        return EVP_aes_128_gcm();
+
+    case NID_aes_128_ofb128:
+        return EVP_aes_128_ofb();
+
+    case NID_aes_128_xts:
+        return EVP_aes_128_xts();
+
+    case NID_aes_192_cbc:
+        return EVP_aes_192_cbc();
+
+    case NID_aes_192_ccm:
+        return EVP_aes_192_ccm();
+
+    case NID_aes_192_cfb1:
+        return EVP_aes_192_cfb1();
+
+    case NID_aes_192_cfb128:
+        return EVP_aes_192_cfb128();
+
+    case NID_aes_192_cfb8:
+        return EVP_aes_192_cfb8();
+
+    case NID_aes_192_ctr:
+        return EVP_aes_192_ctr();
+
+    case NID_aes_192_ecb:
+        return EVP_aes_192_ecb();
+
+    case NID_aes_192_gcm:
+        return EVP_aes_192_gcm();
+
+    case NID_aes_192_ofb128:
+        return EVP_aes_192_ofb();
+
+    case NID_aes_256_cbc:
+        return EVP_aes_256_cbc();
+
+    case NID_aes_256_ccm:
+        return EVP_aes_256_ccm();
+
+    case NID_aes_256_cfb1:
+        return EVP_aes_256_cfb1();
+
+    case NID_aes_256_cfb128:
+        return EVP_aes_256_cfb128();
+
+    case NID_aes_256_cfb8:
+        return EVP_aes_256_cfb8();
+
+    case NID_aes_256_ctr:
+        return EVP_aes_256_ctr();
+
+    case NID_aes_256_ecb:
+        return EVP_aes_256_ecb();
+
+    case NID_aes_256_gcm:
+        return EVP_aes_256_gcm();
+
+    case NID_aes_256_ofb128:
+        return EVP_aes_256_ofb();
+
+    case NID_aes_256_xts:
+        return EVP_aes_256_xts();
+
+    case NID_des_ede_ecb:
+        return EVP_des_ede();
+
+    case NID_des_ede3_ecb:
+        return EVP_des_ede3();
+
+    case NID_des_ede3_cbc:
+        return EVP_des_ede3_cbc();
+
+    case NID_des_ede3_cfb1:
+        return EVP_des_ede3_cfb1();
+
+    case NID_des_ede3_cfb64:
+        return EVP_des_ede3_cfb64();
+
+    case NID_des_ede3_cfb8:
+        return EVP_des_ede3_cfb8();
+
+    case NID_des_ede3_ofb64:
+        return EVP_des_ede3_ofb();
+
+    case NID_des_ede_cbc:
+        return EVP_des_ede_cbc();
+
+    case NID_des_ede_cfb64:
+        return EVP_des_ede_cfb64();
+
+    case NID_des_ede_ofb64:
+        return EVP_des_ede_ofb();
+
+    default:
+        return NULL;
+
+    }
+}
diff -up openssl-1.0.2i/crypto/fips/fips.h.fips openssl-1.0.2i/crypto/fips/fips.h
--- openssl-1.0.2i/crypto/fips/fips.h.fips	2016-09-22 13:35:57.017220997 +0200
+++ openssl-1.0.2i/crypto/fips/fips.h	2016-09-22 13:35:57.017220997 +0200
@@ -0,0 +1,278 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#include <openssl/crypto.h>
+#include <stdarg.h>
+
+#ifndef OPENSSL_FIPS
+# error FIPS is disabled.
+#endif
+
+#ifdef OPENSSL_FIPS
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+    struct dsa_st;
+    struct rsa_st;
+    struct evp_pkey_st;
+    struct env_md_st;
+    struct env_md_ctx_st;
+    struct evp_cipher_st;
+    struct evp_cipher_ctx_st;
+    struct dh_method;
+    struct CMAC_CTX_st;
+    struct hmac_ctx_st;
+
+    int FIPS_module_mode_set(int onoff, const char *auth);
+    int FIPS_module_mode(void);
+    const void *FIPS_rand_check(void);
+    int FIPS_selftest(void);
+    int FIPS_selftest_failed(void);
+    void FIPS_corrupt_sha1(void);
+    int FIPS_selftest_sha1(void);
+    int FIPS_selftest_sha2(void);
+    void FIPS_corrupt_aes(void);
+    int FIPS_selftest_aes_ccm(void);
+    int FIPS_selftest_aes_gcm(void);
+    int FIPS_selftest_aes_xts(void);
+    int FIPS_selftest_aes(void);
+    void FIPS_corrupt_des(void);
+    int FIPS_selftest_des(void);
+    void FIPS_corrupt_rsa(void);
+    void FIPS_corrupt_rsa_keygen(void);
+    int FIPS_selftest_rsa(void);
+    void FIPS_corrupt_dsa(void);
+    void FIPS_corrupt_dsa_keygen(void);
+    int FIPS_selftest_dsa(void);
+    void FIPS_corrupt_rng(void);
+    void FIPS_rng_stick(void);
+    void FIPS_x931_stick(int onoff);
+    void FIPS_drbg_stick(int onoff);
+    int FIPS_selftest_rng(void);
+    int FIPS_selftest_x931(void);
+    int FIPS_selftest_hmac(void);
+    int FIPS_selftest_drbg(void);
+    int FIPS_selftest_drbg_all(void);
+    int FIPS_selftest_cmac(void);
+
+    void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr);
+
+# define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \
+                alg " previous FIPS forbidden algorithm error ignored");
+
+    int fips_pkey_signature_test(struct evp_pkey_st *pkey,
+                                 const unsigned char *tbs, int tbslen,
+                                 const unsigned char *kat,
+                                 unsigned int katlen,
+                                 const struct env_md_st *digest,
+                                 unsigned int md_flags, const char *fail_str);
+
+    int fips_cipher_test(struct evp_cipher_ctx_st *ctx,
+                         const struct evp_cipher_st *cipher,
+                         const unsigned char *key,
+                         const unsigned char *iv,
+                         const unsigned char *plaintext,
+                         const unsigned char *ciphertext, int len);
+
+    void fips_set_selftest_fail(void);
+
+    const struct env_md_st *FIPS_get_digestbynid(int nid);
+
+    const struct evp_cipher_st *FIPS_get_cipherbynid(int nid);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+    void ERR_load_FIPS_strings(void);
+
+/* Error codes for the FIPS functions. */
+
+/* Function codes. */
+# define FIPS_F_DH_BUILTIN_GENPARAMS                      100
+# define FIPS_F_DH_INIT                                   148
+# define FIPS_F_DRBG_RESEED                               162
+# define FIPS_F_DSA_BUILTIN_PARAMGEN                      101
+# define FIPS_F_DSA_BUILTIN_PARAMGEN2                     107
+# define FIPS_F_DSA_DO_SIGN                               102
+# define FIPS_F_DSA_DO_VERIFY                             103
+# define FIPS_F_ECDH_COMPUTE_KEY                          163
+# define FIPS_F_ECDSA_DO_SIGN                             164
+# define FIPS_F_ECDSA_DO_VERIFY                           165
+# define FIPS_F_EC_KEY_GENERATE_KEY                       166
+# define FIPS_F_EVP_CIPHERINIT_EX                         124
+# define FIPS_F_EVP_DIGESTINIT_EX                         125
+# define FIPS_F_FIPS_CHECK_DSA                            104
+# define FIPS_F_FIPS_CHECK_DSA_PRNG                       151
+# define FIPS_F_FIPS_CHECK_EC                             142
+# define FIPS_F_FIPS_CHECK_EC_PRNG                        152
+# define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT             105
+# define FIPS_F_FIPS_CHECK_RSA                            106
+# define FIPS_F_FIPS_CHECK_RSA_PRNG                       150
+# define FIPS_F_FIPS_CIPHER                               160
+# define FIPS_F_FIPS_CIPHERINIT                           143
+# define FIPS_F_FIPS_CIPHER_CTX_CTRL                      161
+# define FIPS_F_FIPS_DIGESTFINAL                          158
+# define FIPS_F_FIPS_DIGESTINIT                           128
+# define FIPS_F_FIPS_DIGESTUPDATE                         159
+# define FIPS_F_FIPS_DRBG_BYTES                           131
+# define FIPS_F_FIPS_DRBG_CHECK                           146
+# define FIPS_F_FIPS_DRBG_CPRNG_TEST                      132
+# define FIPS_F_FIPS_DRBG_ERROR_CHECK                     136
+# define FIPS_F_FIPS_DRBG_GENERATE                        134
+# define FIPS_F_FIPS_DRBG_INIT                            135
+# define FIPS_F_FIPS_DRBG_INSTANTIATE                     138
+# define FIPS_F_FIPS_DRBG_NEW                             139
+# define FIPS_F_FIPS_DRBG_RESEED                          140
+# define FIPS_F_FIPS_DRBG_SINGLE_KAT                      141
+# define FIPS_F_FIPS_DSA_CHECK           /* unused */     107
+# define FIPS_F_FIPS_DSA_SIGN_DIGEST                      154
+# define FIPS_F_FIPS_DSA_VERIFY_DIGEST                    155
+# define FIPS_F_FIPS_GET_ENTROPY                          147
+# define FIPS_F_FIPS_MODE_SET            /* unused */     108
+# define FIPS_F_FIPS_MODULE_MODE_SET                      108
+# define FIPS_F_FIPS_PKEY_SIGNATURE_TEST                  109
+# define FIPS_F_FIPS_RAND_ADD                             137
+# define FIPS_F_FIPS_RAND_BYTES                           122
+# define FIPS_F_FIPS_RAND_PSEUDO_BYTES                    167
+# define FIPS_F_FIPS_RAND_SEED                            168
+# define FIPS_F_FIPS_RAND_SET_METHOD                      126
+# define FIPS_F_FIPS_RAND_STATUS                          127
+# define FIPS_F_FIPS_RSA_SIGN_DIGEST                      156
+# define FIPS_F_FIPS_RSA_VERIFY_DIGEST                    157
+# define FIPS_F_FIPS_SELFTEST_AES                         110
+# define FIPS_F_FIPS_SELFTEST_AES_CCM                     145
+# define FIPS_F_FIPS_SELFTEST_AES_GCM                     129
+# define FIPS_F_FIPS_SELFTEST_AES_XTS                     144
+# define FIPS_F_FIPS_SELFTEST_CMAC                        130
+# define FIPS_F_FIPS_SELFTEST_DES                         111
+# define FIPS_F_FIPS_SELFTEST_DSA                         112
+# define FIPS_F_FIPS_SELFTEST_ECDSA                       133
+# define FIPS_F_FIPS_SELFTEST_HMAC                        113
+# define FIPS_F_FIPS_SELFTEST_RNG        /* unused */     114
+# define FIPS_F_FIPS_SELFTEST_SHA1                        115
+# define FIPS_F_FIPS_SELFTEST_X931                        114
+# define FIPS_F_FIPS_SET_PRNG_KEY                         153
+# define FIPS_F_HASH_FINAL                                123
+# define FIPS_F_RSA_BUILTIN_KEYGEN                        116
+# define FIPS_F_RSA_EAY_INIT                              149
+# define FIPS_F_RSA_EAY_PRIVATE_DECRYPT                   117
+# define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT                   118
+# define FIPS_F_RSA_EAY_PUBLIC_DECRYPT                    119
+# define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT                    120
+# define FIPS_F_RSA_X931_GENERATE_KEY_EX                  121
+# define FIPS_F_SSLEAY_RAND_BYTES        /* unused */     122
+
+/* Reason codes. */
+# define FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED         150
+# define FIPS_R_ADDITIONAL_INPUT_TOO_LONG                 125
+# define FIPS_R_ALREADY_INSTANTIATED                      134
+# define FIPS_R_AUTHENTICATION_FAILURE                    151
+# define FIPS_R_CANNOT_READ_EXE          /* unused */     103
+# define FIPS_R_CANNOT_READ_EXE_DIGEST   /* unused */     104
+# define FIPS_R_CONTRADICTING_EVIDENCE                    114
+# define FIPS_R_DRBG_NOT_INITIALISED                      152
+# define FIPS_R_DRBG_STUCK                                103
+# define FIPS_R_ENTROPY_ERROR_UNDETECTED                  104
+# define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED          105
+# define FIPS_R_ENTROPY_SOURCE_STUCK                      142
+# define FIPS_R_ERROR_INITIALISING_DRBG                   115
+# define FIPS_R_ERROR_INSTANTIATING_DRBG                  127
+# define FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT         124
+# define FIPS_R_ERROR_RETRIEVING_ENTROPY                  122
+# define FIPS_R_ERROR_RETRIEVING_NONCE                    140
+# define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH   /* unused */  105
+# define FIPS_R_FINGERPRINT_DOES_NOT_MATCH                110
+# define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111
+# define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112
+# define FIPS_R_FIPS_MODE_ALREADY_SET                     102
+# define FIPS_R_FIPS_SELFTEST_FAILED                      106
+# define FIPS_R_FUNCTION_ERROR                            116
+# define FIPS_R_GENERATE_ERROR                            137
+# define FIPS_R_GENERATE_ERROR_UNDETECTED                 118
+# define FIPS_R_INSTANTIATE_ERROR                         119
+# define FIPS_R_INSUFFICIENT_SECURITY_STRENGTH            120
+# define FIPS_R_INTERNAL_ERROR                            121
+# define FIPS_R_INVALID_KEY_LENGTH                        109
+# define FIPS_R_INVALID_PARAMETERS                        144
+# define FIPS_R_IN_ERROR_STATE                            123
+# define FIPS_R_KEY_TOO_SHORT                             108
+# define FIPS_R_NONCE_ERROR_UNDETECTED                    149
+# define FIPS_R_NON_FIPS_METHOD                           100
+# define FIPS_R_NOPR_TEST1_FAILURE                        145
+# define FIPS_R_NOPR_TEST2_FAILURE                        146
+# define FIPS_R_NOT_INSTANTIATED                          126
+# define FIPS_R_PAIRWISE_TEST_FAILED                      107
+# define FIPS_R_PERSONALISATION_ERROR_UNDETECTED          128
+# define FIPS_R_PERSONALISATION_STRING_TOO_LONG           129
+# define FIPS_R_PRNG_STRENGTH_TOO_LOW                     143
+# define FIPS_R_PR_TEST1_FAILURE                          147
+# define FIPS_R_PR_TEST2_FAILURE                          148
+# define FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED           130
+# define FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG                131
+# define FIPS_R_RESEED_COUNTER_ERROR                      132
+# define FIPS_R_RESEED_ERROR                              133
+# define FIPS_R_RSA_DECRYPT_ERROR        /* unused */     115
+# define FIPS_R_RSA_ENCRYPT_ERROR        /* unused */     116
+# define FIPS_R_SELFTEST_FAILED                           101
+# define FIPS_R_SELFTEST_FAILURE                          135
+# define FIPS_R_STRENGTH_ERROR_UNDETECTED                 136
+# define FIPS_R_TEST_FAILURE                              117
+# define FIPS_R_UNINSTANTIATE_ERROR                       141
+# define FIPS_R_UNINSTANTIATE_ZEROISE_ERROR               138
+# define FIPS_R_UNSUPPORTED_DRBG_TYPE                     139
+# define FIPS_R_UNSUPPORTED_PLATFORM                      113
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c.fips	2016-09-22 13:35:57.017220997 +0200
+++ openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c	2016-09-22 13:35:57.017220997 +0200
@@ -0,0 +1,134 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include <openssl/hmac.h>
+
+#ifdef OPENSSL_FIPS
+typedef struct {
+    const EVP_MD *(*alg) (void);
+    const char *key, *iv;
+    unsigned char kaval[EVP_MAX_MD_SIZE];
+} HMAC_KAT;
+
+static const HMAC_KAT vector[] = {
+    {EVP_sha1,
+     /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */
+     "0123456789:;<=>?@ABC",
+     "Sample #2",
+     {0x09, 0x22, 0xd3, 0x40, 0x5f, 0xaa, 0x3d, 0x19,
+      0x4f, 0x82, 0xa4, 0x58, 0x30, 0x73, 0x7d, 0x5c,
+      0xc6, 0xc7, 0x5d, 0x24}
+     },
+    {EVP_sha224,
+     /* just keep extending the above... */
+     "0123456789:;<=>?@ABC",
+     "Sample #2",
+     {0xdd, 0xef, 0x0a, 0x40, 0xcb, 0x7d, 0x50, 0xfb,
+      0x6e, 0xe6, 0xce, 0xa1, 0x20, 0xba, 0x26, 0xaa,
+      0x08, 0xf3, 0x07, 0x75, 0x87, 0xb8, 0xad, 0x1b,
+      0x8c, 0x8d, 0x12, 0xc7}
+     },
+    {EVP_sha256,
+     "0123456789:;<=>?@ABC",
+     "Sample #2",
+     {0xb8, 0xf2, 0x0d, 0xb5, 0x41, 0xea, 0x43, 0x09,
+      0xca, 0x4e, 0xa9, 0x38, 0x0c, 0xd0, 0xe8, 0x34,
+      0xf7, 0x1f, 0xbe, 0x91, 0x74, 0xa2, 0x61, 0x38,
+      0x0d, 0xc1, 0x7e, 0xae, 0x6a, 0x34, 0x51, 0xd9}
+     },
+    {EVP_sha384,
+     "0123456789:;<=>?@ABC",
+     "Sample #2",
+     {0x08, 0xbc, 0xb0, 0xda, 0x49, 0x1e, 0x87, 0xad,
+      0x9a, 0x1d, 0x6a, 0xce, 0x23, 0xc5, 0x0b, 0xf6,
+      0xb7, 0x18, 0x06, 0xa5, 0x77, 0xcd, 0x49, 0x04,
+      0x89, 0xf1, 0xe6, 0x23, 0x44, 0x51, 0x51, 0x9f,
+      0x85, 0x56, 0x80, 0x79, 0x0c, 0xbd, 0x4d, 0x50,
+      0xa4, 0x5f, 0x29, 0xe3, 0x93, 0xf0, 0xe8, 0x7f}
+     },
+    {EVP_sha512,
+     "0123456789:;<=>?@ABC",
+     "Sample #2",
+     {0x80, 0x9d, 0x44, 0x05, 0x7c, 0x5b, 0x95, 0x41,
+      0x05, 0xbd, 0x04, 0x13, 0x16, 0xdb, 0x0f, 0xac,
+      0x44, 0xd5, 0xa4, 0xd5, 0xd0, 0x89, 0x2b, 0xd0,
+      0x4e, 0x86, 0x64, 0x12, 0xc0, 0x90, 0x77, 0x68,
+      0xf1, 0x87, 0xb7, 0x7c, 0x4f, 0xae, 0x2c, 0x2f,
+      0x21, 0xa5, 0xb5, 0x65, 0x9a, 0x4f, 0x4b, 0xa7,
+      0x47, 0x02, 0xa3, 0xde, 0x9b, 0x51, 0xf1, 0x45,
+      0xbd, 0x4f, 0x25, 0x27, 0x42, 0x98, 0x99, 0x05}
+     },
+};
+
+int FIPS_selftest_hmac()
+{
+    int n;
+    unsigned int outlen;
+    unsigned char out[EVP_MAX_MD_SIZE];
+    const EVP_MD *md;
+    const HMAC_KAT *t;
+
+    for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) {
+        md = (*t->alg) ();
+        HMAC(md, t->key, strlen(t->key),
+             (const unsigned char *)t->iv, strlen(t->iv), out, &outlen);
+
+        if (memcmp(out, t->kaval, outlen)) {
+            FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC, FIPS_R_SELFTEST_FAILED);
+            return 0;
+        }
+    }
+    return 1;
+}
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_locl.h.fips openssl-1.0.2i/crypto/fips/fips_locl.h
--- openssl-1.0.2i/crypto/fips/fips_locl.h.fips	2016-09-22 13:35:57.017220997 +0200
+++ openssl-1.0.2i/crypto/fips/fips_locl.h	2016-09-22 13:35:57.017220997 +0200
@@ -0,0 +1,71 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef OPENSSL_FIPS
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define FIPS_MAX_CIPHER_TEST_SIZE       32
+# define fips_load_key_component(key, comp, pre) \
+        key->comp = BN_bin2bn(pre##_##comp, sizeof(pre##_##comp), key->comp); \
+        if (!key->comp) \
+                goto err
+
+# define fips_post_started(id, subid, ex) 1
+# define fips_post_success(id, subid, ex) 1
+# define fips_post_failed(id, subid, ex) 1
+# define fips_post_corrupt(id, subid, ex) 1
+# define fips_post_status() 1
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_md.c.fips openssl-1.0.2i/crypto/fips/fips_md.c
--- openssl-1.0.2i/crypto/fips/fips_md.c.fips	2016-09-22 13:35:57.017220997 +0200
+++ openssl-1.0.2i/crypto/fips/fips_md.c	2016-09-22 13:35:57.017220997 +0200
@@ -0,0 +1,144 @@
+/* fips/evp/fips_md.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Minimal standalone FIPS versions of Digest operations */
+
+#define OPENSSL_FIPSAPI
+
+#include <stdio.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+const EVP_MD *FIPS_get_digestbynid(int nid)
+{
+    switch (nid) {
+    case NID_sha1:
+        return EVP_sha1();
+
+    case NID_sha224:
+        return EVP_sha224();
+
+    case NID_sha256:
+        return EVP_sha256();
+
+    case NID_sha384:
+        return EVP_sha384();
+
+    case NID_sha512:
+        return EVP_sha512();
+
+    default:
+        return NULL;
+    }
+}
diff -up openssl-1.0.2i/crypto/fips/fips_post.c.fips openssl-1.0.2i/crypto/fips/fips_post.c
--- openssl-1.0.2i/crypto/fips/fips_post.c.fips	2016-09-22 13:35:57.017220997 +0200
+++ openssl-1.0.2i/crypto/fips/fips_post.c	2016-09-22 13:35:57.017220997 +0200
@@ -0,0 +1,201 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/err.h>
+#include <openssl/bio.h>
+#include <openssl/hmac.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <string.h>
+#include <limits.h>
+
+#ifdef OPENSSL_FIPS
+
+/* Power on self test (POST) support functions */
+
+# include <openssl/fips.h>
+# include "fips_locl.h"
+
+/* Run all selftests */
+int FIPS_selftest(void)
+{
+    int rv = 1;
+    if (!FIPS_selftest_drbg())
+        rv = 0;
+    if (!FIPS_selftest_x931())
+        rv = 0;
+    if (!FIPS_selftest_sha1())
+        rv = 0;
+    if (!FIPS_selftest_sha2())
+        rv = 0;
+    if (!FIPS_selftest_hmac())
+        rv = 0;
+    if (!FIPS_selftest_cmac())
+        rv = 0;
+    if (!FIPS_selftest_aes())
+        rv = 0;
+    if (!FIPS_selftest_aes_ccm())
+        rv = 0;
+    if (!FIPS_selftest_aes_gcm())
+        rv = 0;
+    if (!FIPS_selftest_aes_xts())
+        rv = 0;
+    if (!FIPS_selftest_des())
+        rv = 0;
+    if (!FIPS_selftest_rsa())
+        rv = 0;
+    if (!FIPS_selftest_dsa())
+        rv = 0;
+    return rv;
+}
+
+/* Generalized public key test routine. Signs and verifies the data
+ * supplied in tbs using mesage digest md and setting option digest
+ * flags md_flags. If the 'kat' parameter is not NULL it will
+ * additionally check the signature matches it: a known answer test
+ * The string "fail_str" is used for identification purposes in case
+ * of failure. If "pkey" is NULL just perform a message digest check.
+ */
+
+int fips_pkey_signature_test(EVP_PKEY *pkey,
+                             const unsigned char *tbs, int tbslen,
+                             const unsigned char *kat, unsigned int katlen,
+                             const EVP_MD *digest, unsigned int md_flags,
+                             const char *fail_str)
+{
+    int ret = 0;
+    unsigned char sigtmp[256], *sig = sigtmp;
+    unsigned int siglen;
+    EVP_MD_CTX mctx;
+    EVP_MD_CTX_init(&mctx);
+
+    if (digest == NULL)
+        digest = EVP_sha256();
+
+    if ((pkey->type == EVP_PKEY_RSA)
+        && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp))) {
+        sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa));
+        if (!sig) {
+            FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+
+    if (tbslen == -1)
+        tbslen = strlen((char *)tbs);
+
+    if (md_flags)
+        EVP_MD_CTX_set_flags(&mctx, md_flags);
+
+    if (!EVP_SignInit_ex(&mctx, digest, NULL))
+        goto error;
+    if (!EVP_SignUpdate(&mctx, tbs, tbslen))
+        goto error;
+    if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
+        goto error;
+
+    if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
+        goto error;
+
+    if (!EVP_VerifyInit_ex(&mctx, digest, NULL))
+        goto error;
+    if (!EVP_VerifyUpdate(&mctx, tbs, tbslen))
+        goto error;
+    ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
+
+ error:
+    if (sig != sigtmp)
+        OPENSSL_free(sig);
+    EVP_MD_CTX_cleanup(&mctx);
+    if (ret != 1) {
+        FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST, FIPS_R_TEST_FAILURE);
+        if (fail_str)
+            ERR_add_error_data(2, "Type=", fail_str);
+        return 0;
+    }
+    return 1;
+}
+
+/* Generalized symmetric cipher test routine. Encrypt data, verify result
+ * against known answer, decrypt and compare with original plaintext.
+ */
+
+int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                     const unsigned char *key,
+                     const unsigned char *iv,
+                     const unsigned char *plaintext,
+                     const unsigned char *ciphertext, int len)
+{
+    unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE];
+    unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE];
+
+    OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE);
+    memset(pltmp, 0, FIPS_MAX_CIPHER_TEST_SIZE);
+    memset(citmp, 0, FIPS_MAX_CIPHER_TEST_SIZE);
+
+    if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0)
+        return 0;
+    if (EVP_Cipher(ctx, citmp, plaintext, len) <= 0)
+        return 0;
+    if (memcmp(citmp, ciphertext, len))
+        return 0;
+    if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0)
+        return 0;
+    if (EVP_Cipher(ctx, pltmp, citmp, len) <= 0)
+        return 0;
+    if (memcmp(pltmp, plaintext, len))
+        return 0;
+    return 1;
+}
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_rand.c.fips openssl-1.0.2i/crypto/fips/fips_rand.c
--- openssl-1.0.2i/crypto/fips/fips_rand.c.fips	2016-09-22 13:35:57.018221020 +0200
+++ openssl-1.0.2i/crypto/fips/fips_rand.c	2016-09-22 13:35:57.018221020 +0200
@@ -0,0 +1,428 @@
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4.
+ */
+#include <openssl/crypto.h>
+#include "e_os.h"
+
+/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't
+   be defined and gettimeofday() won't be declared with strict compilers
+   like DEC C in ANSI C mode.  */
+#ifndef _XOPEN_SOURCE_EXTENDED
+# define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/fips_rand.h>
+#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS))
+# include <sys/time.h>
+#endif
+#if defined(OPENSSL_SYS_VXWORKS)
+# include <time.h>
+#endif
+#include <assert.h>
+#ifndef OPENSSL_SYS_WIN32
+# ifdef OPENSSL_UNISTD
+#  include OPENSSL_UNISTD
+# else
+#  include <unistd.h>
+# endif
+#endif
+#include <string.h>
+#include <openssl/fips.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+void *OPENSSL_stderr(void);
+
+# define AES_BLOCK_LENGTH        16
+
+/* AES FIPS PRNG implementation */
+
+typedef struct {
+    int seeded;
+    int keyed;
+    int test_mode;
+    int second;
+    int error;
+    unsigned long counter;
+    AES_KEY ks;
+    int vpos;
+    /* Temporary storage for key if it equals seed length */
+    unsigned char tmp_key[AES_BLOCK_LENGTH];
+    unsigned char V[AES_BLOCK_LENGTH];
+    unsigned char DT[AES_BLOCK_LENGTH];
+    unsigned char last[AES_BLOCK_LENGTH];
+} FIPS_PRNG_CTX;
+
+static FIPS_PRNG_CTX sctx;
+
+static int fips_prng_fail = 0;
+
+void FIPS_x931_stick(int onoff)
+{
+    fips_prng_fail = onoff;
+}
+
+void FIPS_rng_stick(void)
+{
+    FIPS_x931_stick(1);
+}
+
+static void fips_rand_prng_reset(FIPS_PRNG_CTX * ctx)
+{
+    ctx->seeded = 0;
+    ctx->keyed = 0;
+    ctx->test_mode = 0;
+    ctx->counter = 0;
+    ctx->second = 0;
+    ctx->error = 0;
+    ctx->vpos = 0;
+    OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH);
+    OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY));
+}
+
+static int fips_set_prng_key(FIPS_PRNG_CTX * ctx,
+                             const unsigned char *key, unsigned int keylen)
+{
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_FIPS_SET_PRNG_KEY, FIPS_R_SELFTEST_FAILED);
+        return 0;
+    }
+    if (keylen != 16 && keylen != 24 && keylen != 32) {
+        /* error: invalid key size */
+        return 0;
+    }
+    AES_set_encrypt_key(key, keylen << 3, &ctx->ks);
+    if (keylen == 16) {
+        memcpy(ctx->tmp_key, key, 16);
+        ctx->keyed = 2;
+    } else
+        ctx->keyed = 1;
+    ctx->seeded = 0;
+    ctx->second = 0;
+    return 1;
+}
+
+static int fips_set_prng_seed(FIPS_PRNG_CTX * ctx,
+                              const unsigned char *seed, unsigned int seedlen)
+{
+    unsigned int i;
+    if (!ctx->keyed)
+        return 0;
+    /* In test mode seed is just supplied data */
+    if (ctx->test_mode) {
+        if (seedlen != AES_BLOCK_LENGTH)
+            return 0;
+        memcpy(ctx->V, seed, AES_BLOCK_LENGTH);
+        ctx->seeded = 1;
+        return 1;
+    }
+    /* Outside test mode XOR supplied data with existing seed */
+    for (i = 0; i < seedlen; i++) {
+        ctx->V[ctx->vpos++] ^= seed[i];
+        if (ctx->vpos == AES_BLOCK_LENGTH) {
+            ctx->vpos = 0;
+            /* Special case if first seed and key length equals
+             * block size check key and seed do not match.
+             */
+            if (ctx->keyed == 2) {
+                if (!memcmp(ctx->tmp_key, ctx->V, 16)) {
+                    RANDerr(RAND_F_FIPS_SET_PRNG_SEED,
+                            RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY);
+                    return 0;
+                }
+                OPENSSL_cleanse(ctx->tmp_key, 16);
+                ctx->keyed = 1;
+            }
+            ctx->seeded = 1;
+        }
+    }
+    return 1;
+}
+
+static int fips_set_test_mode(FIPS_PRNG_CTX * ctx)
+{
+    if (ctx->keyed) {
+        RANDerr(RAND_F_FIPS_SET_TEST_MODE, RAND_R_PRNG_KEYED);
+        return 0;
+    }
+    ctx->test_mode = 1;
+    return 1;
+}
+
+int FIPS_x931_test_mode(void)
+{
+    return fips_set_test_mode(&sctx);
+}
+
+int FIPS_rand_test_mode(void)
+{
+    return fips_set_test_mode(&sctx);
+}
+
+int FIPS_x931_set_dt(unsigned char *dt)
+{
+    if (!sctx.test_mode) {
+        RANDerr(RAND_F_FIPS_X931_SET_DT, RAND_R_NOT_IN_TEST_MODE);
+        return 0;
+    }
+    memcpy(sctx.DT, dt, AES_BLOCK_LENGTH);
+    return 1;
+}
+
+int FIPS_rand_set_dt(unsigned char *dt)
+{
+    if (!sctx.test_mode) {
+        RANDerr(RAND_F_FIPS_RAND_SET_DT, RAND_R_NOT_IN_TEST_MODE);
+        return 0;
+    }
+    memcpy(sctx.DT, dt, AES_BLOCK_LENGTH);
+    return 1;
+}
+
+void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr)
+{
+# ifdef OPENSSL_SYS_WIN32
+    FILETIME ft;
+# elif defined(OPENSSL_SYS_VXWORKS)
+    struct timespec ts;
+# else
+    struct timeval tv;
+# endif
+
+# ifndef GETPID_IS_MEANINGLESS
+    unsigned long pid;
+# endif
+
+# ifdef OPENSSL_SYS_WIN32
+    GetSystemTimeAsFileTime(&ft);
+    buf[0] = (unsigned char)(ft.dwHighDateTime & 0xff);
+    buf[1] = (unsigned char)((ft.dwHighDateTime >> 8) & 0xff);
+    buf[2] = (unsigned char)((ft.dwHighDateTime >> 16) & 0xff);
+    buf[3] = (unsigned char)((ft.dwHighDateTime >> 24) & 0xff);
+    buf[4] = (unsigned char)(ft.dwLowDateTime & 0xff);
+    buf[5] = (unsigned char)((ft.dwLowDateTime >> 8) & 0xff);
+    buf[6] = (unsigned char)((ft.dwLowDateTime >> 16) & 0xff);
+    buf[7] = (unsigned char)((ft.dwLowDateTime >> 24) & 0xff);
+# elif defined(OPENSSL_SYS_VXWORKS)
+    clock_gettime(CLOCK_REALTIME, &ts);
+    buf[0] = (unsigned char)(ts.tv_sec & 0xff);
+    buf[1] = (unsigned char)((ts.tv_sec >> 8) & 0xff);
+    buf[2] = (unsigned char)((ts.tv_sec >> 16) & 0xff);
+    buf[3] = (unsigned char)((ts.tv_sec >> 24) & 0xff);
+    buf[4] = (unsigned char)(ts.tv_nsec & 0xff);
+    buf[5] = (unsigned char)((ts.tv_nsec >> 8) & 0xff);
+    buf[6] = (unsigned char)((ts.tv_nsec >> 16) & 0xff);
+    buf[7] = (unsigned char)((ts.tv_nsec >> 24) & 0xff);
+# else
+    gettimeofday(&tv, NULL);
+    buf[0] = (unsigned char)(tv.tv_sec & 0xff);
+    buf[1] = (unsigned char)((tv.tv_sec >> 8) & 0xff);
+    buf[2] = (unsigned char)((tv.tv_sec >> 16) & 0xff);
+    buf[3] = (unsigned char)((tv.tv_sec >> 24) & 0xff);
+    buf[4] = (unsigned char)(tv.tv_usec & 0xff);
+    buf[5] = (unsigned char)((tv.tv_usec >> 8) & 0xff);
+    buf[6] = (unsigned char)((tv.tv_usec >> 16) & 0xff);
+    buf[7] = (unsigned char)((tv.tv_usec >> 24) & 0xff);
+# endif
+    buf[8] = (unsigned char)(*pctr & 0xff);
+    buf[9] = (unsigned char)((*pctr >> 8) & 0xff);
+    buf[10] = (unsigned char)((*pctr >> 16) & 0xff);
+    buf[11] = (unsigned char)((*pctr >> 24) & 0xff);
+
+    (*pctr)++;
+
+# ifndef GETPID_IS_MEANINGLESS
+    pid = (unsigned long)getpid();
+    buf[12] = (unsigned char)(pid & 0xff);
+    buf[13] = (unsigned char)((pid >> 8) & 0xff);
+    buf[14] = (unsigned char)((pid >> 16) & 0xff);
+    buf[15] = (unsigned char)((pid >> 24) & 0xff);
+# endif
+}
+
+static int fips_rand(FIPS_PRNG_CTX * ctx,
+                     unsigned char *out, unsigned int outlen)
+{
+    unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH];
+    unsigned char tmp[AES_BLOCK_LENGTH];
+    int i;
+    if (ctx->error) {
+        RANDerr(RAND_F_FIPS_RAND, RAND_R_PRNG_ERROR);
+        return 0;
+    }
+    if (!ctx->keyed) {
+        RANDerr(RAND_F_FIPS_RAND, RAND_R_NO_KEY_SET);
+        return 0;
+    }
+    if (!ctx->seeded) {
+        RANDerr(RAND_F_FIPS_RAND, RAND_R_PRNG_NOT_SEEDED);
+        return 0;
+    }
+    for (;;) {
+        if (!ctx->test_mode)
+            FIPS_get_timevec(ctx->DT, &ctx->counter);
+        AES_encrypt(ctx->DT, I, &ctx->ks);
+        for (i = 0; i < AES_BLOCK_LENGTH; i++)
+            tmp[i] = I[i] ^ ctx->V[i];
+        AES_encrypt(tmp, R, &ctx->ks);
+        for (i = 0; i < AES_BLOCK_LENGTH; i++)
+            tmp[i] = R[i] ^ I[i];
+        AES_encrypt(tmp, ctx->V, &ctx->ks);
+        /* Continuous PRNG test */
+        if (ctx->second) {
+            if (fips_prng_fail)
+                memcpy(ctx->last, R, AES_BLOCK_LENGTH);
+            if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH)) {
+                RANDerr(RAND_F_FIPS_RAND, RAND_R_PRNG_STUCK);
+                ctx->error = 1;
+                fips_set_selftest_fail();
+                return 0;
+            }
+        }
+        memcpy(ctx->last, R, AES_BLOCK_LENGTH);
+        if (!ctx->second) {
+            ctx->second = 1;
+            if (!ctx->test_mode)
+                continue;
+        }
+
+        if (outlen <= AES_BLOCK_LENGTH) {
+            memcpy(out, R, outlen);
+            break;
+        }
+
+        memcpy(out, R, AES_BLOCK_LENGTH);
+        out += AES_BLOCK_LENGTH;
+        outlen -= AES_BLOCK_LENGTH;
+    }
+    return 1;
+}
+
+int FIPS_x931_set_key(const unsigned char *key, int keylen)
+{
+    int ret;
+    CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+    ret = fips_set_prng_key(&sctx, key, keylen);
+    CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+    return ret;
+}
+
+int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen)
+{
+    return FIPS_x931_set_key(key, keylen);
+}
+
+int FIPS_x931_seed(const void *seed, int seedlen)
+{
+    int ret;
+    CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+    ret = fips_set_prng_seed(&sctx, seed, seedlen);
+    CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+    return ret;
+}
+
+int FIPS_x931_bytes(unsigned char *out, int count)
+{
+    int ret;
+    CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+    ret = fips_rand(&sctx, out, count);
+    CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+    return ret;
+}
+
+int FIPS_x931_status(void)
+{
+    int ret;
+    CRYPTO_r_lock(CRYPTO_LOCK_RAND);
+    ret = sctx.seeded;
+    CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
+    return ret;
+}
+
+void FIPS_x931_reset(void)
+{
+    CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+    fips_rand_prng_reset(&sctx);
+    CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+}
+
+static int fips_do_rand_seed(const void *seed, int seedlen)
+{
+    FIPS_x931_seed(seed, seedlen);
+    return 1;
+}
+
+static int fips_do_rand_add(const void *seed, int seedlen, double add_entropy)
+{
+    FIPS_x931_seed(seed, seedlen);
+    return 1;
+}
+
+static const RAND_METHOD rand_x931_meth = {
+    fips_do_rand_seed,
+    FIPS_x931_bytes,
+    FIPS_x931_reset,
+    fips_do_rand_add,
+    FIPS_x931_bytes,
+    FIPS_x931_status
+};
+
+const RAND_METHOD *FIPS_x931_method(void)
+{
+    return &rand_x931_meth;
+}
+
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_rand.h.fips openssl-1.0.2i/crypto/fips/fips_rand.h
--- openssl-1.0.2i/crypto/fips/fips_rand.h.fips	2016-09-22 13:35:57.018221020 +0200
+++ openssl-1.0.2i/crypto/fips/fips_rand.h	2016-09-22 13:35:57.018221020 +0200
@@ -0,0 +1,163 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef HEADER_FIPS_RAND_H
+# define HEADER_FIPS_RAND_H
+
+# include <openssl/aes.h>
+# include <openssl/evp.h>
+# include <openssl/hmac.h>
+# include <openssl/rand.h>
+
+# ifdef OPENSSL_FIPS
+
+#  ifdef  __cplusplus
+extern "C" {
+#  endif
+
+    int FIPS_x931_set_key(const unsigned char *key, int keylen);
+    int FIPS_x931_seed(const void *buf, int num);
+    int FIPS_x931_bytes(unsigned char *out, int outlen);
+
+    int FIPS_x931_test_mode(void);
+    void FIPS_x931_reset(void);
+    int FIPS_x931_set_dt(unsigned char *dt);
+
+    int FIPS_x931_status(void);
+
+    const RAND_METHOD *FIPS_x931_method(void);
+
+    typedef struct drbg_ctx_st DRBG_CTX;
+/* DRBG external flags */
+/* Flag for CTR mode only: use derivation function ctr_df */
+#  define DRBG_FLAG_CTR_USE_DF            0x1
+/* PRNG is in test state */
+#  define DRBG_FLAG_TEST                  0x2
+
+    DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags);
+    int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags);
+    int FIPS_drbg_instantiate(DRBG_CTX *dctx,
+                              const unsigned char *pers, size_t perslen);
+    int FIPS_drbg_reseed(DRBG_CTX *dctx, const unsigned char *adin,
+                         size_t adinlen);
+    int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
+                           int prediction_resistance,
+                           const unsigned char *adin, size_t adinlen);
+
+    int FIPS_drbg_uninstantiate(DRBG_CTX *dctx);
+    void FIPS_drbg_free(DRBG_CTX *dctx);
+
+    int FIPS_drbg_set_callbacks(DRBG_CTX *dctx,
+                                size_t (*get_entropy) (DRBG_CTX *ctx,
+                                                       unsigned char **pout,
+                                                       int entropy,
+                                                       size_t min_len,
+                                                       size_t max_len),
+                                void (*cleanup_entropy) (DRBG_CTX *ctx,
+                                                         unsigned char *out,
+                                                         size_t olen),
+                                size_t entropy_blocklen,
+                                size_t (*get_nonce) (DRBG_CTX *ctx,
+                                                     unsigned char **pout,
+                                                     int entropy,
+                                                     size_t min_len,
+                                                     size_t max_len),
+                                void (*cleanup_nonce) (DRBG_CTX *ctx,
+                                                       unsigned char *out,
+                                                       size_t olen));
+
+    int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx,
+                                     size_t (*get_adin) (DRBG_CTX *ctx,
+                                                         unsigned char
+                                                         **pout),
+                                     void (*cleanup_adin) (DRBG_CTX *ctx,
+                                                           unsigned char *out,
+                                                           size_t olen),
+                                     int (*rand_seed_cb) (DRBG_CTX *ctx,
+                                                          const void *buf,
+                                                          int num),
+                                     int (*rand_add_cb) (DRBG_CTX *ctx,
+                                                         const void *buf,
+                                                         int num,
+                                                         double entropy));
+
+    void *FIPS_drbg_get_app_data(DRBG_CTX *ctx);
+    void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data);
+    size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx);
+    int FIPS_drbg_get_strength(DRBG_CTX *dctx);
+    void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval);
+    void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval);
+
+    int FIPS_drbg_health_check(DRBG_CTX *dctx);
+
+    DRBG_CTX *FIPS_get_default_drbg(void);
+    const RAND_METHOD *FIPS_drbg_method(void);
+
+    int FIPS_rand_set_method(const RAND_METHOD *meth);
+    const RAND_METHOD *FIPS_rand_get_method(void);
+
+    void FIPS_rand_set_bits(int nbits);
+
+    int FIPS_rand_strength(void);
+
+/* 1.0.0 compat functions */
+    int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen);
+    int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num);
+    int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen);
+    int FIPS_rand_test_mode(void);
+    void FIPS_rand_reset(void);
+    int FIPS_rand_set_dt(unsigned char *dt);
+    int FIPS_rand_status(void);
+    const RAND_METHOD *FIPS_rand_method(void);
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_rand_lcl.h.fips openssl-1.0.2i/crypto/fips/fips_rand_lcl.h
--- openssl-1.0.2i/crypto/fips/fips_rand_lcl.h.fips	2016-09-22 13:35:57.018221020 +0200
+++ openssl-1.0.2i/crypto/fips/fips_rand_lcl.h	2016-09-22 13:35:57.018221020 +0200
@@ -0,0 +1,213 @@
+/* fips/rand/fips_rand_lcl.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+typedef struct drbg_hash_ctx_st DRBG_HASH_CTX;
+typedef struct drbg_hmac_ctx_st DRBG_HMAC_CTX;
+typedef struct drbg_ctr_ctx_st DRBG_CTR_CTX;
+
+/* 888 bits from 10.1 table 2 */
+#define HASH_PRNG_MAX_SEEDLEN   111
+
+struct drbg_hash_ctx_st {
+    const EVP_MD *md;
+    EVP_MD_CTX mctx;
+    unsigned char V[HASH_PRNG_MAX_SEEDLEN];
+    unsigned char C[HASH_PRNG_MAX_SEEDLEN];
+    /* Temporary value storage: should always exceed max digest length */
+    unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN];
+};
+
+struct drbg_hmac_ctx_st {
+    const EVP_MD *md;
+    HMAC_CTX hctx;
+    unsigned char K[EVP_MAX_MD_SIZE];
+    unsigned char V[EVP_MAX_MD_SIZE];
+};
+
+struct drbg_ctr_ctx_st {
+    AES_KEY ks;
+    size_t keylen;
+    unsigned char K[32];
+    unsigned char V[16];
+    /* Temp variables used by derivation function */
+    AES_KEY df_ks;
+    AES_KEY df_kxks;
+    /* Temporary block storage used by ctr_df */
+    unsigned char bltmp[16];
+    size_t bltmp_pos;
+    unsigned char KX[48];
+};
+
+/* DRBG internal flags */
+
+/* Functions shouldn't call err library */
+#define DRBG_FLAG_NOERR                 0x1
+/* Custom reseed checking */
+#define DRBG_CUSTOM_RESEED              0x2
+
+/* DRBG status values */
+/* not initialised */
+#define DRBG_STATUS_UNINITIALISED       0
+/* ok and ready to generate random bits */
+#define DRBG_STATUS_READY               1
+/* reseed required */
+#define DRBG_STATUS_RESEED              2
+/* fatal error condition */
+#define DRBG_STATUS_ERROR               3
+
+/* A default maximum length: larger than any reasonable value used in pratice */
+
+#define DRBG_MAX_LENGTH                 0x7ffffff0
+/* Maximum DRBG block length: all md sizes are bigger than cipher blocks sizes
+ * so use max digest length.
+ */
+#define DRBG_MAX_BLOCK                  EVP_MAX_MD_SIZE
+
+#define DRBG_HEALTH_INTERVAL            (1 << 24)
+
+/* DRBG context structure */
+
+struct drbg_ctx_st {
+    /* First types common to all implementations */
+    /* DRBG type: a NID for the underlying algorithm */
+    int type;
+    /* Various external flags */
+    unsigned int xflags;
+    /* Various internal use only flags */
+    unsigned int iflags;
+    /* Used for periodic health checks */
+    int health_check_cnt, health_check_interval;
+
+    /* The following parameters are setup by mechanism drbg_init() call */
+    int strength;
+    size_t blocklength;
+    size_t max_request;
+
+    size_t min_entropy, max_entropy;
+    size_t min_nonce, max_nonce;
+    size_t max_pers, max_adin;
+    unsigned int reseed_counter;
+    unsigned int reseed_interval;
+    size_t seedlen;
+    int status;
+    /* Application data: typically used by test get_entropy */
+    void *app_data;
+    /* Implementation specific structures */
+    union {
+        DRBG_HASH_CTX hash;
+        DRBG_HMAC_CTX hmac;
+        DRBG_CTR_CTX ctr;
+    } d;
+    /* Initialiase PRNG and setup callbacks below */
+    int (*init) (DRBG_CTX *ctx, int nid, int security, unsigned int flags);
+    /* Intantiate PRNG */
+    int (*instantiate) (DRBG_CTX *ctx,
+                        const unsigned char *ent, size_t entlen,
+                        const unsigned char *nonce, size_t noncelen,
+                        const unsigned char *pers, size_t perslen);
+    /* reseed */
+    int (*reseed) (DRBG_CTX *ctx,
+                   const unsigned char *ent, size_t entlen,
+                   const unsigned char *adin, size_t adinlen);
+    /* generat output */
+    int (*generate) (DRBG_CTX *ctx,
+                     unsigned char *out, size_t outlen,
+                     const unsigned char *adin, size_t adinlen);
+    /* uninstantiate */
+    int (*uninstantiate) (DRBG_CTX *ctx);
+
+    /* Entropy source block length */
+    size_t entropy_blocklen;
+
+    /* entropy gathering function */
+    size_t (*get_entropy) (DRBG_CTX *ctx, unsigned char **pout,
+                           int entropy, size_t min_len, size_t max_len);
+    /* Indicates we have finished with entropy buffer */
+    void (*cleanup_entropy) (DRBG_CTX *ctx, unsigned char *out, size_t olen);
+
+    /* nonce gathering function */
+    size_t (*get_nonce) (DRBG_CTX *ctx, unsigned char **pout,
+                         int entropy, size_t min_len, size_t max_len);
+    /* Indicates we have finished with nonce buffer */
+    void (*cleanup_nonce) (DRBG_CTX *ctx, unsigned char *out, size_t olen);
+
+    /* Continuous random number test temporary area */
+    /* Last block */
+    unsigned char lb[EVP_MAX_MD_SIZE];
+    /* set if lb is valid */
+    int lb_valid;
+
+    /* Callbacks used when called through RAND interface */
+    /* Get any additional input for generate */
+    size_t (*get_adin) (DRBG_CTX *ctx, unsigned char **pout);
+    void (*cleanup_adin) (DRBG_CTX *ctx, unsigned char *out, size_t olen);
+    /* Callback for RAND_seed(), RAND_add() */
+    int (*rand_seed_cb) (DRBG_CTX *ctx, const void *buf, int num);
+    int (*rand_add_cb) (DRBG_CTX *ctx,
+                        const void *buf, int num, double entropy);
+};
+
+int fips_drbg_ctr_init(DRBG_CTX *dctx);
+int fips_drbg_hash_init(DRBG_CTX *dctx);
+int fips_drbg_hmac_init(DRBG_CTX *dctx);
+int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags);
+int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out);
+
+const struct env_md_st *FIPS_get_digestbynid(int nid);
+
+const struct evp_cipher_st *FIPS_get_cipherbynid(int nid);
+
+#define FIPS_digestinit EVP_DigestInit
+#define FIPS_digestupdate EVP_DigestUpdate
+#define FIPS_digestfinal EVP_DigestFinal
+#define M_EVP_MD_size EVP_MD_size
diff -up openssl-1.0.2i/crypto/fips/fips_rand_lib.c.fips openssl-1.0.2i/crypto/fips/fips_rand_lib.c
--- openssl-1.0.2i/crypto/fips/fips_rand_lib.c.fips	2016-09-22 13:35:57.018221020 +0200
+++ openssl-1.0.2i/crypto/fips/fips_rand_lib.c	2016-09-22 13:35:57.018221020 +0200
@@ -0,0 +1,181 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#include "e_os.h"
+
+/* FIPS API for PRNG use. Similar to RAND functionality but without
+ * ENGINE and additional checking for non-FIPS rand methods.
+ */
+
+static const RAND_METHOD *fips_rand_meth = NULL;
+static int fips_approved_rand_meth = 0;
+static int fips_rand_bits = 0;
+
+/* Allows application to override number of bits and uses non-FIPS methods */
+void FIPS_rand_set_bits(int nbits)
+{
+    fips_rand_bits = nbits;
+}
+
+int FIPS_rand_set_method(const RAND_METHOD *meth)
+{
+    if (!fips_rand_bits) {
+        if (meth == FIPS_drbg_method())
+            fips_approved_rand_meth = 1;
+        else if (meth == FIPS_x931_method())
+            fips_approved_rand_meth = 2;
+        else {
+            fips_approved_rand_meth = 0;
+            if (FIPS_module_mode()) {
+                FIPSerr(FIPS_F_FIPS_RAND_SET_METHOD, FIPS_R_NON_FIPS_METHOD);
+                return 0;
+            }
+        }
+    }
+    fips_rand_meth = meth;
+    return 1;
+}
+
+const RAND_METHOD *FIPS_rand_get_method(void)
+{
+    return fips_rand_meth;
+}
+
+const RAND_METHOD *FIPS_rand_method(void)
+{
+    return FIPS_rand_get_method();
+}
+
+void FIPS_rand_reset(void)
+{
+    if (fips_rand_meth && fips_rand_meth->cleanup)
+        fips_rand_meth->cleanup();
+}
+
+int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num)
+{
+    if (!fips_approved_rand_meth && FIPS_module_mode()) {
+        FIPSerr(FIPS_F_FIPS_RAND_SEED, FIPS_R_NON_FIPS_METHOD);
+        return 0;
+    }
+    if (fips_rand_meth && fips_rand_meth->seed)
+        fips_rand_meth->seed(buf, num);
+    return 1;
+}
+
+void FIPS_rand_add(const void *buf, int num, double entropy)
+{
+    if (!fips_approved_rand_meth && FIPS_module_mode()) {
+        FIPSerr(FIPS_F_FIPS_RAND_ADD, FIPS_R_NON_FIPS_METHOD);
+        return;
+    }
+    if (fips_rand_meth && fips_rand_meth->add)
+        fips_rand_meth->add(buf, num, entropy);
+}
+
+int FIPS_rand_bytes(unsigned char *buf, FIPS_RAND_SIZE_T num)
+{
+    if (!fips_approved_rand_meth && FIPS_module_mode()) {
+        FIPSerr(FIPS_F_FIPS_RAND_BYTES, FIPS_R_NON_FIPS_METHOD);
+        return 0;
+    }
+    if (fips_rand_meth && fips_rand_meth->bytes)
+        return fips_rand_meth->bytes(buf, num);
+    return 0;
+}
+
+int FIPS_rand_pseudo_bytes(unsigned char *buf, int num)
+{
+    if (!fips_approved_rand_meth && FIPS_module_mode()) {
+        FIPSerr(FIPS_F_FIPS_RAND_PSEUDO_BYTES, FIPS_R_NON_FIPS_METHOD);
+        return 0;
+    }
+    if (fips_rand_meth && fips_rand_meth->pseudorand)
+        return fips_rand_meth->pseudorand(buf, num);
+    return -1;
+}
+
+int FIPS_rand_status(void)
+{
+    if (!fips_approved_rand_meth && FIPS_module_mode()) {
+        FIPSerr(FIPS_F_FIPS_RAND_STATUS, FIPS_R_NON_FIPS_METHOD);
+        return 0;
+    }
+    if (fips_rand_meth && fips_rand_meth->status)
+        return fips_rand_meth->status();
+    return 0;
+}
+
+/* Return instantiated strength of PRNG. For DRBG this is an internal
+ * parameter. For X9.31 PRNG it is 80 bits (from SP800-131). Any other
+ * type of PRNG is not approved and returns 0 in FIPS mode and maximum
+ * 256 outside FIPS mode.
+ */
+
+int FIPS_rand_strength(void)
+{
+    if (fips_rand_bits)
+        return fips_rand_bits;
+    if (fips_approved_rand_meth == 1)
+        return FIPS_drbg_get_strength(FIPS_get_default_drbg());
+    else if (fips_approved_rand_meth == 2)
+        return 80;
+    else if (fips_approved_rand_meth == 0) {
+        if (FIPS_module_mode())
+            return 0;
+        else
+            return 256;
+    }
+    return 0;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_rand_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_rand_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_rand_selftest.c.fips	2016-09-22 13:35:57.018221020 +0200
+++ openssl-1.0.2i/crypto/fips/fips_rand_selftest.c	2016-09-22 13:35:57.018221020 +0200
@@ -0,0 +1,176 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+typedef struct {
+    unsigned char DT[16];
+    unsigned char V[16];
+    unsigned char R[16];
+} AES_PRNG_TV;
+
+/* The following test vectors are taken directly from the RGNVS spec */
+
+static unsigned char aes_128_key[16] =
+    { 0xf3, 0xb1, 0x66, 0x6d, 0x13, 0x60, 0x72, 0x42,
+    0xed, 0x06, 0x1c, 0xab, 0xb8, 0xd4, 0x62, 0x02
+};
+
+static AES_PRNG_TV aes_128_tv = {
+    /* DT */
+    {0xe6, 0xb3, 0xbe, 0x78, 0x2a, 0x23, 0xfa, 0x62,
+     0xd7, 0x1d, 0x4a, 0xfb, 0xb0, 0xe9, 0x22, 0xf9},
+    /* V */
+    {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    /* R */
+    {0x59, 0x53, 0x1e, 0xd1, 0x3b, 0xb0, 0xc0, 0x55,
+     0x84, 0x79, 0x66, 0x85, 0xc1, 0x2f, 0x76, 0x41}
+};
+
+static unsigned char aes_192_key[24] =
+    { 0x15, 0xd8, 0x78, 0x0d, 0x62, 0xd3, 0x25, 0x6e,
+    0x44, 0x64, 0x10, 0x13, 0x60, 0x2b, 0xa9, 0xbc,
+    0x4a, 0xfb, 0xca, 0xeb, 0x4c, 0x8b, 0x99, 0x3b
+};
+
+static AES_PRNG_TV aes_192_tv = {
+    /* DT */
+    {0x3f, 0xd8, 0xff, 0xe8, 0x80, 0x69, 0x8b, 0xc1,
+     0xbf, 0x99, 0x7d, 0xa4, 0x24, 0x78, 0xf3, 0x4b},
+    /* V */
+    {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    /* R */
+    {0x17, 0x07, 0xd5, 0x28, 0x19, 0x79, 0x1e, 0xef,
+     0xa5, 0x0c, 0xbf, 0x25, 0xe5, 0x56, 0xb4, 0x93}
+};
+
+static unsigned char aes_256_key[32] =
+    { 0x6d, 0x14, 0x06, 0x6c, 0xb6, 0xd8, 0x21, 0x2d,
+    0x82, 0x8d, 0xfa, 0xf2, 0x7a, 0x03, 0xb7, 0x9f,
+    0x0c, 0xc7, 0x3e, 0xcd, 0x76, 0xeb, 0xee, 0xb5,
+    0x21, 0x05, 0x8c, 0x4f, 0x31, 0x7a, 0x80, 0xbb
+};
+
+static AES_PRNG_TV aes_256_tv = {
+    /* DT */
+    {0xda, 0x3a, 0x41, 0xec, 0x1d, 0xa3, 0xb0, 0xd5,
+     0xf2, 0xa9, 0x4e, 0x34, 0x74, 0x8e, 0x9e, 0x88},
+    /* V */
+    {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    /* R */
+    {0x35, 0xc7, 0xef, 0xa7, 0x78, 0x4d, 0x29, 0xbc,
+     0x82, 0x79, 0x99, 0xfb, 0xd0, 0xb3, 0x3b, 0x72}
+};
+
+void FIPS_corrupt_rng()
+{
+    aes_192_tv.V[0]++;
+}
+
+# define fips_x931_test(key, tv) \
+        do_x931_test(key, sizeof key, &tv)
+
+static int do_x931_test(unsigned char *key, int keylen, AES_PRNG_TV * tv)
+{
+    unsigned char R[16], V[16];
+    int rv = 1;
+    memcpy(V, tv->V, sizeof(V));
+    if (!FIPS_x931_set_key(key, keylen))
+        return 0;
+    if (!fips_post_started(FIPS_TEST_X931, keylen, NULL))
+        return 1;
+    if (!fips_post_corrupt(FIPS_TEST_X931, keylen, NULL))
+        V[0]++;
+    FIPS_x931_seed(V, 16);
+    FIPS_x931_set_dt(tv->DT);
+    FIPS_x931_bytes(R, 16);
+    if (memcmp(R, tv->R, 16)) {
+        fips_post_failed(FIPS_TEST_X931, keylen, NULL);
+        rv = 0;
+    } else if (!fips_post_success(FIPS_TEST_X931, keylen, NULL))
+        return 0;
+    return rv;
+}
+
+int FIPS_selftest_x931()
+{
+    int rv = 1;
+    FIPS_x931_reset();
+    if (!FIPS_x931_test_mode()) {
+        FIPSerr(FIPS_F_FIPS_SELFTEST_X931, FIPS_R_SELFTEST_FAILED);
+        return 0;
+    }
+    if (!fips_x931_test(aes_128_key, aes_128_tv))
+        rv = 0;
+    if (!fips_x931_test(aes_192_key, aes_192_tv))
+        rv = 0;
+    if (!fips_x931_test(aes_256_key, aes_256_tv))
+        rv = 0;
+    FIPS_x931_reset();
+    if (!rv)
+        FIPSerr(FIPS_F_FIPS_SELFTEST_X931, FIPS_R_SELFTEST_FAILED);
+    return rv;
+}
+
+int FIPS_selftest_rng(void)
+{
+    return FIPS_selftest_x931();
+}
+
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_randtest.c.fips openssl-1.0.2i/crypto/fips/fips_randtest.c
--- openssl-1.0.2i/crypto/fips/fips_randtest.c.fips	2016-09-22 13:35:57.018221020 +0200
+++ openssl-1.0.2i/crypto/fips/fips_randtest.c	2016-09-22 13:35:57.018221020 +0200
@@ -0,0 +1,247 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+#include "e_os.h"
+
+#ifndef OPENSSL_FIPS
+int main(int argc, char *argv[])
+{
+    printf("No FIPS RAND support\n");
+    return (0);
+}
+
+#else
+
+# include "fips_utl.h"
+# include <openssl/fips.h>
+
+typedef struct {
+    unsigned char DT[16];
+    unsigned char V[16];
+    unsigned char R[16];
+} AES_PRNG_MCT;
+
+static const unsigned char aes_128_mct_key[16] =
+    { 0x9f, 0x5b, 0x51, 0x20, 0x0b, 0xf3, 0x34, 0xb5,
+    0xd8, 0x2b, 0xe8, 0xc3, 0x72, 0x55, 0xc8, 0x48
+};
+
+static const AES_PRNG_MCT aes_128_mct_tv = {
+    /* DT */
+    {0x63, 0x76, 0xbb, 0xe5, 0x29, 0x02, 0xba, 0x3b,
+     0x67, 0xc9, 0x25, 0xfa, 0x70, 0x1f, 0x11, 0xac},
+    /* V */
+    {0x57, 0x2c, 0x8e, 0x76, 0x87, 0x26, 0x47, 0x97,
+     0x7e, 0x74, 0xfb, 0xdd, 0xc4, 0x95, 0x01, 0xd1},
+    /* R */
+    {0x48, 0xe9, 0xbd, 0x0d, 0x06, 0xee, 0x18, 0xfb,
+     0xe4, 0x57, 0x90, 0xd5, 0xc3, 0xfc, 0x9b, 0x73}
+};
+
+static const unsigned char aes_192_mct_key[24] =
+    { 0xb7, 0x6c, 0x34, 0xd1, 0x09, 0x67, 0xab, 0x73,
+    0x4d, 0x5a, 0xd5, 0x34, 0x98, 0x16, 0x0b, 0x91,
+    0xbc, 0x35, 0x51, 0x16, 0x6b, 0xae, 0x93, 0x8a
+};
+
+static const AES_PRNG_MCT aes_192_mct_tv = {
+    /* DT */
+    {0x84, 0xce, 0x22, 0x7d, 0x91, 0x5a, 0xa3, 0xc9,
+     0x84, 0x3c, 0x0a, 0xb3, 0xa9, 0x63, 0x15, 0x52},
+    /* V */
+    {0xb6, 0xaf, 0xe6, 0x8f, 0x99, 0x9e, 0x90, 0x64,
+     0xdd, 0xc7, 0x7a, 0xc1, 0xbb, 0x90, 0x3a, 0x6d},
+    /* R */
+    {0xfc, 0x85, 0x60, 0x9a, 0x29, 0x6f, 0xef, 0x21,
+     0xdd, 0x86, 0x20, 0x32, 0x8a, 0x29, 0x6f, 0x47}
+};
+
+static const unsigned char aes_256_mct_key[32] =
+    { 0x9b, 0x05, 0xc8, 0x68, 0xff, 0x47, 0xf8, 0x3a,
+    0xa6, 0x3a, 0xa8, 0xcb, 0x4e, 0x71, 0xb2, 0xe0,
+    0xb8, 0x7e, 0xf1, 0x37, 0xb6, 0xb4, 0xf6, 0x6d,
+    0x86, 0x32, 0xfc, 0x1f, 0x5e, 0x1d, 0x1e, 0x50
+};
+
+static const AES_PRNG_MCT aes_256_mct_tv = {
+    /* DT */
+    {0x31, 0x6e, 0x35, 0x9a, 0xb1, 0x44, 0xf0, 0xee,
+     0x62, 0x6d, 0x04, 0x46, 0xe0, 0xa3, 0x92, 0x4c},
+    /* V */
+    {0x4f, 0xcd, 0xc1, 0x87, 0x82, 0x1f, 0x4d, 0xa1,
+     0x3e, 0x0e, 0x56, 0x44, 0x59, 0xe8, 0x83, 0xca},
+    /* R */
+    {0xc8, 0x87, 0xc2, 0x61, 0x5b, 0xd0, 0xb9, 0xe1,
+     0xe7, 0xf3, 0x8b, 0xd7, 0x5b, 0xd5, 0xf1, 0x8d}
+};
+
+static void dump(const unsigned char *b, int n)
+{
+    while (n-- > 0) {
+        printf(" %02x", *b++);
+    }
+}
+
+static void compare(const unsigned char *result,
+                    const unsigned char *expected, int n)
+{
+    int i;
+
+    for (i = 0; i < n; ++i)
+        if (result[i] != expected[i]) {
+            puts("Random test failed, got:");
+            dump(result, n);
+            puts("\n               expected:");
+            dump(expected, n);
+            putchar('\n');
+            EXIT(1);
+        }
+}
+
+static void run_test(const unsigned char *key, int keylen,
+                     const AES_PRNG_MCT * tv)
+{
+    unsigned char buf[16], dt[16];
+    int i, j;
+    FIPS_x931_reset();
+    FIPS_x931_test_mode();
+    FIPS_x931_set_key(key, keylen);
+    FIPS_x931_seed(tv->V, 16);
+    memcpy(dt, tv->DT, 16);
+    for (i = 0; i < 10000; i++) {
+        FIPS_x931_set_dt(dt);
+        FIPS_x931_bytes(buf, 16);
+        /* Increment DT */
+        for (j = 15; j >= 0; j--) {
+            dt[j]++;
+            if (dt[j])
+                break;
+        }
+    }
+
+    compare(buf, tv->R, 16);
+}
+
+int main()
+{
+    run_test(aes_128_mct_key, 16, &aes_128_mct_tv);
+    printf("FIPS PRNG test 1 done\n");
+    run_test(aes_192_mct_key, 24, &aes_192_mct_tv);
+    printf("FIPS PRNG test 2 done\n");
+    run_test(aes_256_mct_key, 32, &aes_256_mct_tv);
+    printf("FIPS PRNG test 3 done\n");
+    return 0;
+}
+
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c.fips	2016-09-22 13:35:57.019221043 +0200
+++ openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c	2016-09-22 13:35:57.019221043 +0200
@@ -0,0 +1,444 @@
+/* ====================================================================
+ * Copyright (c) 2003-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+
+static const unsigned char n[] =
+    "\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
+    "\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
+    "\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
+    "\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
+    "\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
+    "\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
+    "\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
+    "\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD" "\xCB";
+
+static int corrupt_rsa;
+
+static int setrsakey(RSA *key)
+{
+    static const unsigned char e[] = "\x11";
+
+    static const unsigned char d[] =
+        "\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
+        "\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
+        "\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
+        "\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
+        "\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
+        "\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
+        "\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
+        "\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
+        "\xC1";
+
+    static const unsigned char p[] =
+        "\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
+        "\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
+        "\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
+        "\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
+        "\x99";
+
+    static const unsigned char q[] =
+        "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+        "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+        "\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+        "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
+        "\x03";
+
+    static const unsigned char dmp1[] =
+        "\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
+        "\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
+        "\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
+        "\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
+
+    static const unsigned char dmq1[] =
+        "\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
+        "\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
+        "\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
+        "\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
+
+    static const unsigned char iqmp[] =
+        "\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
+        "\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
+        "\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
+        "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
+        "\xF7";
+
+    key->n = BN_bin2bn(n, sizeof(n) - 1, key->n);
+    if (corrupt_rsa)
+        BN_set_bit(key->n, 1024);
+    key->e = BN_bin2bn(e, sizeof(e) - 1, key->e);
+    key->d = BN_bin2bn(d, sizeof(d) - 1, key->d);
+    key->p = BN_bin2bn(p, sizeof(p) - 1, key->p);
+    key->q = BN_bin2bn(q, sizeof(q) - 1, key->q);
+    key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1) - 1, key->dmp1);
+    key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1) - 1, key->dmq1);
+    key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp) - 1, key->iqmp);
+    return 1;
+}
+
+void FIPS_corrupt_rsa()
+{
+    corrupt_rsa = 1;
+}
+
+/* Known Answer Test (KAT) data for the above RSA private key signing
+ * kat_tbs.
+ */
+
+static const unsigned char kat_tbs[] =
+    "OpenSSL FIPS 140-2 Public Key RSA KAT";
+
+static const unsigned char kat_RSA_PSS_SHA1[] = {
+    0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F,
+    0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB,
+    0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3,
+    0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C,
+    0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7,
+    0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5,
+    0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45,
+    0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31,
+    0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8,
+    0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84,
+    0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9
+};
+
+static const unsigned char kat_RSA_PSS_SHA224[] = {
+    0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7,
+    0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA,
+    0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57,
+    0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89,
+    0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE,
+    0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22,
+    0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5,
+    0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49,
+    0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D,
+    0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00,
+    0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0
+};
+
+static const unsigned char kat_RSA_PSS_SHA256[] = {
+    0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89,
+    0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F,
+    0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28,
+    0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E,
+    0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05,
+    0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA,
+    0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6,
+    0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F,
+    0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D,
+    0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6,
+    0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C
+};
+
+static const unsigned char kat_RSA_PSS_SHA384[] = {
+    0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2,
+    0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E,
+    0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD,
+    0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F,
+    0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C,
+    0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB,
+    0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F,
+    0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89,
+    0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F,
+    0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55,
+    0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1
+};
+
+static const unsigned char kat_RSA_PSS_SHA512[] = {
+    0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C,
+    0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A,
+    0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD,
+    0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39,
+    0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7,
+    0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61,
+    0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13,
+    0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63,
+    0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE,
+    0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88,
+    0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B
+};
+
+static const unsigned char kat_RSA_SHA1[] = {
+    0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C,
+    0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B,
+    0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF,
+    0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,
+    0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1,
+    0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA,
+    0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E,
+    0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,
+    0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F,
+    0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95,
+    0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4
+};
+
+static const unsigned char kat_RSA_SHA224[] = {
+    0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9,
+    0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D,
+    0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89,
+    0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD,
+    0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5,
+    0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC,
+    0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B,
+    0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2,
+    0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35,
+    0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC,
+    0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D
+};
+
+static const unsigned char kat_RSA_SHA256[] = {
+    0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23,
+    0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23,
+    0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35,
+    0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E,
+    0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18,
+    0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30,
+    0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A,
+    0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38,
+    0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA,
+    0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90,
+    0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A
+};
+
+static const unsigned char kat_RSA_SHA384[] = {
+    0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F,
+    0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7,
+    0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C,
+    0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55,
+    0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF,
+    0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2,
+    0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C,
+    0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD,
+    0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1,
+    0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04,
+    0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF
+};
+
+static const unsigned char kat_RSA_SHA512[] = {
+    0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF,
+    0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A,
+    0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1,
+    0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8,
+    0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5,
+    0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B,
+    0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6,
+    0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05,
+    0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D,
+    0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91,
+    0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84
+};
+
+static const unsigned char kat_RSA_X931_SHA1[] = {
+    0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF,
+    0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75,
+    0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC,
+    0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97,
+    0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6,
+    0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19,
+    0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7,
+    0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99,
+    0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76,
+    0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67,
+    0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49
+};
+
+static const unsigned char kat_RSA_X931_SHA256[] = {
+    0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89,
+    0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD,
+    0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF,
+    0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B,
+    0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B,
+    0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98,
+    0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC,
+    0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C,
+    0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD,
+    0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC,
+    0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80
+};
+
+static const unsigned char kat_RSA_X931_SHA384[] = {
+    0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B,
+    0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB,
+    0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3,
+    0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6,
+    0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31,
+    0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1,
+    0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79,
+    0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF,
+    0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35,
+    0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D,
+    0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28
+};
+
+static const unsigned char kat_RSA_X931_SHA512[] = {
+    0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63,
+    0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC,
+    0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7,
+    0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28,
+    0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5,
+    0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF,
+    0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0,
+    0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09,
+    0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C,
+    0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B,
+    0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3
+};
+
+int FIPS_selftest_rsa()
+{
+    int ret = 0;
+    RSA *key;
+    EVP_PKEY *pk = NULL;
+
+    if ((key = RSA_new()) == NULL)
+        goto err;
+    setrsakey(key);
+    if ((pk = EVP_PKEY_new()) == NULL)
+        goto err;
+
+    EVP_PKEY_assign_RSA(pk, key);
+
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_SHA1, sizeof(kat_RSA_SHA1),
+                                  EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                                  "RSA SHA1 PKCS#1"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_SHA224, sizeof(kat_RSA_SHA224),
+                                  EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                                  "RSA SHA224 PKCS#1"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_SHA256, sizeof(kat_RSA_SHA256),
+                                  EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                                  "RSA SHA256 PKCS#1"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_SHA384, sizeof(kat_RSA_SHA384),
+                                  EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                                  "RSA SHA384 PKCS#1"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_SHA512, sizeof(kat_RSA_SHA512),
+                                  EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                                  "RSA SHA512 PKCS#1"))
+        goto err;
+
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1),
+                                  EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS,
+                                  "RSA SHA1 PSS"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_PSS_SHA224,
+                                  sizeof(kat_RSA_PSS_SHA224), EVP_sha224(),
+                                  EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA224 PSS"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_PSS_SHA256,
+                                  sizeof(kat_RSA_PSS_SHA256), EVP_sha256(),
+                                  EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA256 PSS"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_PSS_SHA384,
+                                  sizeof(kat_RSA_PSS_SHA384), EVP_sha384(),
+                                  EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA384 PSS"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_PSS_SHA512,
+                                  sizeof(kat_RSA_PSS_SHA512), EVP_sha512(),
+                                  EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA512 PSS"))
+        goto err;
+
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_X931_SHA1,
+                                  sizeof(kat_RSA_X931_SHA1), EVP_sha1(),
+                                  EVP_MD_CTX_FLAG_PAD_X931, "RSA SHA1 X931"))
+        goto err;
+    /* NB: SHA224 not supported in X9.31 */
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_X931_SHA256,
+                                  sizeof(kat_RSA_X931_SHA256), EVP_sha256(),
+                                  EVP_MD_CTX_FLAG_PAD_X931,
+                                  "RSA SHA256 X931"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_X931_SHA384,
+                                  sizeof(kat_RSA_X931_SHA384), EVP_sha384(),
+                                  EVP_MD_CTX_FLAG_PAD_X931,
+                                  "RSA SHA384 X931"))
+        goto err;
+    if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1,
+                                  kat_RSA_X931_SHA512,
+                                  sizeof(kat_RSA_X931_SHA512), EVP_sha512(),
+                                  EVP_MD_CTX_FLAG_PAD_X931,
+                                  "RSA SHA512 X931"))
+        goto err;
+
+    ret = 1;
+
+ err:
+    if (pk)
+        EVP_PKEY_free(pk);
+    else if (key)
+        RSA_free(key);
+    return ret;
+}
+
+#endif                          /* def OPENSSL_FIPS */
diff -up openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c.fips openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c
--- openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c.fips	2016-09-22 13:35:57.019221043 +0200
+++ openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c	2016-09-22 13:35:57.019221043 +0200
@@ -0,0 +1,273 @@
+/* crypto/rsa/rsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+
+extern int fips_check_rsa(RSA *rsa);
+#endif
+
+/* X9.31 RSA key derivation and generation */
+
+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
+                       BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2,
+                       const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2,
+                       const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb)
+{
+    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL;
+    BN_CTX *ctx = NULL, *ctx2 = NULL;
+
+    if (!rsa)
+        goto err;
+
+    ctx = BN_CTX_new();
+    if (!ctx)
+        goto err;
+    BN_CTX_start(ctx);
+
+    r0 = BN_CTX_get(ctx);
+    r1 = BN_CTX_get(ctx);
+    r2 = BN_CTX_get(ctx);
+    r3 = BN_CTX_get(ctx);
+
+    if (r3 == NULL)
+        goto err;
+    if (!rsa->e) {
+        rsa->e = BN_dup(e);
+        if (!rsa->e)
+            goto err;
+    } else
+        e = rsa->e;
+
+    /* If not all parameters present only calculate what we can.
+     * This allows test programs to output selective parameters.
+     */
+
+    if (Xp && !rsa->p) {
+        rsa->p = BN_new();
+        if (!rsa->p)
+            goto err;
+
+        if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
+                                     Xp, Xp1, Xp2, e, ctx, cb))
+            goto err;
+    }
+
+    if (Xq && !rsa->q) {
+        rsa->q = BN_new();
+        if (!rsa->q)
+            goto err;
+        if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
+                                     Xq, Xq1, Xq2, e, ctx, cb))
+            goto err;
+    }
+
+    if (!rsa->p || !rsa->q) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+        return 2;
+    }
+
+    /* Since both primes are set we can now calculate all remaining 
+     * components.
+     */
+
+    /* calculate n */
+    rsa->n = BN_new();
+    if (rsa->n == NULL)
+        goto err;
+    if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
+        goto err;
+
+    /* calculate d */
+    if (!BN_sub(r1, rsa->p, BN_value_one()))
+        goto err;               /* p-1 */
+    if (!BN_sub(r2, rsa->q, BN_value_one()))
+        goto err;               /* q-1 */
+    if (!BN_mul(r0, r1, r2, ctx))
+        goto err;               /* (p-1)(q-1) */
+
+    if (!BN_gcd(r3, r1, r2, ctx))
+        goto err;
+
+    if (!BN_div(r0, NULL, r0, r3, ctx))
+        goto err;               /* LCM((p-1)(q-1)) */
+
+    ctx2 = BN_CTX_new();
+    if (!ctx2)
+        goto err;
+
+    rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */
+    if (rsa->d == NULL)
+        goto err;
+
+    /* calculate d mod (p-1) */
+    rsa->dmp1 = BN_new();
+    if (rsa->dmp1 == NULL)
+        goto err;
+    if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx))
+        goto err;
+
+    /* calculate d mod (q-1) */
+    rsa->dmq1 = BN_new();
+    if (rsa->dmq1 == NULL)
+        goto err;
+    if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx))
+        goto err;
+
+    /* calculate inverse of q mod p */
+    rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2);
+
+ err:
+    if (ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    if (ctx2)
+        BN_CTX_free(ctx2);
+    /* If this is set all calls successful */
+    if (rsa && rsa->iqmp != NULL)
+        return 1;
+
+    return 0;
+
+}
+
+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e,
+                             BN_GENCB *cb)
+{
+    int ok = 0;
+    BIGNUM *Xp = NULL, *Xq = NULL;
+    BN_CTX *ctx = NULL;
+
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) &&
+        (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) {
+        FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX, FIPS_R_KEY_TOO_SHORT);
+        return 0;
+    }
+
+    if (bits & 0xff) {
+        FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX, FIPS_R_INVALID_KEY_LENGTH);
+        return 0;
+    }
+
+    if (FIPS_selftest_failed()) {
+        FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX, FIPS_R_FIPS_SELFTEST_FAILED);
+        return 0;
+    }
+#endif
+
+    ctx = BN_CTX_new();
+    if (!ctx)
+        goto error;
+
+    BN_CTX_start(ctx);
+    Xp = BN_CTX_get(ctx);
+    Xq = BN_CTX_get(ctx);
+    if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
+        goto error;
+
+    rsa->p = BN_new();
+    rsa->q = BN_new();
+    if (!rsa->p || !rsa->q)
+        goto error;
+
+    /* Generate two primes from Xp, Xq */
+
+    if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
+                                   e, ctx, cb))
+        goto error;
+
+    if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
+                                   e, ctx, cb))
+        goto error;
+
+    /* Since rsa->p and rsa->q are valid this call will just derive
+     * remaining RSA components.
+     */
+
+    if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
+                            NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
+        goto error;
+
+#ifdef OPENSSL_FIPS
+    if (!fips_check_rsa(rsa))
+        goto error;
+#endif
+
+    ok = 1;
+
+ error:
+    if (ctx) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+
+    if (ok)
+        return 1;
+
+    return 0;
+
+}
diff -up openssl-1.0.2i/crypto/fips/fips_sha_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_sha_selftest.c
--- openssl-1.0.2i/crypto/fips/fips_sha_selftest.c.fips	2016-09-22 13:35:57.019221043 +0200
+++ openssl-1.0.2i/crypto/fips/fips_sha_selftest.c	2016-09-22 13:35:57.019221043 +0200
@@ -0,0 +1,145 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#ifdef OPENSSL_FIPS
+static const char test[][60] = {
+    "",
+    "abc",
+    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+};
+
+static const unsigned char ret[][SHA_DIGEST_LENGTH] = {
+    {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
+     0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09},
+    {0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e,
+     0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d},
+    {0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae,
+     0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1},
+};
+
+static int corrupt_sha;
+
+void FIPS_corrupt_sha1()
+{
+    corrupt_sha = 1;
+}
+
+int FIPS_selftest_sha1()
+{
+    int n;
+
+    for (n = 0; n < sizeof(test) / sizeof(test[0]); ++n) {
+        unsigned char md[SHA_DIGEST_LENGTH];
+
+        EVP_Digest(test[n], strlen(test[n]) + corrupt_sha, md, NULL,
+                   EVP_sha1(), NULL);
+        if (memcmp(md, ret[n], sizeof md)) {
+            FIPSerr(FIPS_F_FIPS_SELFTEST_SHA1, FIPS_R_SELFTEST_FAILED);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static const unsigned char msg_sha256[] =
+    { 0xfa, 0x48, 0x59, 0x2a, 0xe1, 0xae, 0x1f, 0x30,
+    0xfc
+};
+
+static const unsigned char dig_sha256[] =
+    { 0xf7, 0x26, 0xd8, 0x98, 0x47, 0x91, 0x68, 0x5b,
+    0x9e, 0x39, 0xb2, 0x58, 0xbb, 0x75, 0xbf, 0x01,
+    0x17, 0x0c, 0x84, 0x00, 0x01, 0x7a, 0x94, 0x83,
+    0xf3, 0x0b, 0x15, 0x84, 0x4b, 0x69, 0x88, 0x8a
+};
+
+static const unsigned char msg_sha512[] =
+    { 0x37, 0xd1, 0x35, 0x9d, 0x18, 0x41, 0xe9, 0xb7,
+    0x6d, 0x9a, 0x13, 0xda, 0x5f, 0xf3, 0xbd
+};
+
+static const unsigned char dig_sha512[] =
+    { 0x11, 0x13, 0xc4, 0x19, 0xed, 0x2b, 0x1d, 0x16,
+    0x11, 0xeb, 0x9b, 0xbe, 0xf0, 0x7f, 0xcf, 0x44,
+    0x8b, 0xd7, 0x57, 0xbd, 0x8d, 0xa9, 0x25, 0xb0,
+    0x47, 0x25, 0xd6, 0x6c, 0x9a, 0x54, 0x7f, 0x8f,
+    0x0b, 0x53, 0x1a, 0x10, 0x68, 0x32, 0x03, 0x38,
+    0x82, 0xc4, 0x87, 0xc4, 0xea, 0x0e, 0xd1, 0x04,
+    0xa9, 0x98, 0xc1, 0x05, 0xa3, 0xf3, 0xf8, 0xb1,
+    0xaf, 0xbc, 0xd9, 0x78, 0x7e, 0xee, 0x3d, 0x43
+};
+
+int FIPS_selftest_sha2(void)
+{
+    unsigned char md[SHA512_DIGEST_LENGTH];
+
+    EVP_Digest(msg_sha256, sizeof(msg_sha256), md, NULL, EVP_sha256(), NULL);
+    if (memcmp(dig_sha256, md, sizeof(dig_sha256))) {
+        FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED);
+        return 0;
+    }
+
+    EVP_Digest(msg_sha512, sizeof(msg_sha512), md, NULL, EVP_sha512(), NULL);
+    if (memcmp(dig_sha512, md, sizeof(dig_sha512))) {
+        FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED);
+        return 0;
+    }
+
+    return 1;
+}
+
+#endif
diff -up openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c.fips openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c
--- openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c.fips	2016-09-22 13:35:57.019221043 +0200
+++ openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c	2016-09-22 13:35:57.019221043 +0200
@@ -0,0 +1,268 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/sha.h>
+#include <openssl/hmac.h>
+
+#ifndef FIPSCANISTER_O
+int FIPS_selftest_failed()
+{
+    return 0;
+}
+
+void FIPS_selftest_check()
+{
+}
+#endif
+
+#ifdef OPENSSL_FIPS
+int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                      const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+    return 0;
+};
+
+int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                    const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+    return 0;
+};
+
+# if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
+        defined(__INTEL__) || \
+        defined(__x86_64) || defined(__x86_64__) || \
+        defined(_M_AMD64) || defined(_M_X64)
+
+unsigned int OPENSSL_ia32cap_P[4];
+unsigned long *OPENSSL_ia32cap_loc(void)
+{
+    if (sizeof(long) == 4)
+        /*
+         * If 32-bit application pulls address of OPENSSL_ia32cap_P[0]
+         * clear second element to maintain the illusion that vector
+         * is 32-bit.
+         */
+        OPENSSL_ia32cap_P[1] = 0;
+
+    OPENSSL_ia32cap_P[2] = 0;
+
+    return (unsigned long *)OPENSSL_ia32cap_P;
+}
+
+#  if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
+#   define OPENSSL_CPUID_SETUP
+#   if defined(_WIN32)
+typedef unsigned __int64 IA32CAP;
+#   else
+typedef unsigned long long IA32CAP;
+#   endif
+void OPENSSL_cpuid_setup(void)
+{
+    static int trigger = 0;
+    IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
+    IA32CAP vec;
+    char *env;
+
+    if (trigger)
+        return;
+
+    trigger = 1;
+    if ((env = getenv("OPENSSL_ia32cap"))) {
+        int off = (env[0] == '~') ? 1 : 0;
+#   if defined(_WIN32)
+        if (!sscanf(env + off, "%I64i", &vec))
+            vec = strtoul(env + off, NULL, 0);
+#   else
+        if (!sscanf(env + off, "%lli", (long long *)&vec))
+            vec = strtoul(env + off, NULL, 0);
+#   endif
+        if (off)
+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
+        else if (env[0] == ':')
+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+        OPENSSL_ia32cap_P[2] = 0;
+        if ((env = strchr(env, ':'))) {
+            unsigned int vecx;
+            env++;
+            off = (env[0] == '~') ? 1 : 0;
+            vecx = strtoul(env + off, NULL, 0);
+            if (off)
+                OPENSSL_ia32cap_P[2] &= ~vecx;
+            else
+                OPENSSL_ia32cap_P[2] = vecx;
+        }
+    } else
+        vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+    /*
+     * |(1<<10) sets a reserved bit to signal that variable
+     * was initialized already... This is to avoid interference
+     * with cpuid snippets in ELF .init segment.
+     */
+    OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
+    OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
+}
+#  else
+unsigned int OPENSSL_ia32cap_P[4];
+#  endif
+
+# else
+unsigned long *OPENSSL_ia32cap_loc(void)
+{
+    return NULL;
+}
+# endif
+int OPENSSL_NONPIC_relocated = 0;
+# if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
+void OPENSSL_cpuid_setup(void)
+{
+}
+# endif
+
+static void hmac_init(SHA256_CTX *md_ctx, SHA256_CTX *o_ctx, const char *key)
+{
+    size_t len = strlen(key);
+    int i;
+    unsigned char keymd[HMAC_MAX_MD_CBLOCK];
+    unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+    if (len > SHA_CBLOCK) {
+        SHA256_Init(md_ctx);
+        SHA256_Update(md_ctx, key, len);
+        SHA256_Final(keymd, md_ctx);
+        len = SHA256_DIGEST_LENGTH;
+    } else
+        memcpy(keymd, key, len);
+    memset(&keymd[len], '\0', HMAC_MAX_MD_CBLOCK - len);
+
+    for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
+        pad[i] = 0x36 ^ keymd[i];
+    SHA256_Init(md_ctx);
+    SHA256_Update(md_ctx, pad, SHA256_CBLOCK);
+
+    for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
+        pad[i] = 0x5c ^ keymd[i];
+    SHA256_Init(o_ctx);
+    SHA256_Update(o_ctx, pad, SHA256_CBLOCK);
+}
+
+static void hmac_final(unsigned char *md, SHA256_CTX *md_ctx,
+                       SHA256_CTX *o_ctx)
+{
+    unsigned char buf[SHA256_DIGEST_LENGTH];
+
+    SHA256_Final(buf, md_ctx);
+    SHA256_Update(o_ctx, buf, sizeof buf);
+    SHA256_Final(md, o_ctx);
+}
+
+#endif
+
+int main(int argc, char **argv)
+{
+#ifdef OPENSSL_FIPS
+    static char key[] = "orboDeJITITejsirpADONivirpUkvarP";
+    int n, binary = 0;
+
+    if (argc < 2) {
+        fprintf(stderr, "%s [<file>]+\n", argv[0]);
+        exit(1);
+    }
+
+    n = 1;
+    if (!strcmp(argv[n], "-binary")) {
+        n++;
+        binary = 1;             /* emit binary fingerprint... */
+    }
+
+    for (; n < argc; ++n) {
+        FILE *f = fopen(argv[n], "rb");
+        SHA256_CTX md_ctx, o_ctx;
+        unsigned char md[SHA256_DIGEST_LENGTH];
+        int i;
+
+        if (!f) {
+            perror(argv[n]);
+            exit(2);
+        }
+
+        hmac_init(&md_ctx, &o_ctx, key);
+        for (;;) {
+            char buf[1024];
+            size_t l = fread(buf, 1, sizeof buf, f);
+
+            if (l == 0) {
+                if (ferror(f)) {
+                    perror(argv[n]);
+                    exit(3);
+                } else
+                    break;
+            }
+            SHA256_Update(&md_ctx, buf, l);
+        }
+        hmac_final(md, &md_ctx, &o_ctx);
+
+        if (binary) {
+            fwrite(md, SHA256_DIGEST_LENGTH, 1, stdout);
+            break;              /* ... for single(!) file */
+        }
+
+/*      printf("HMAC-SHA1(%s)= ",argv[n]); */
+        for (i = 0; i < SHA256_DIGEST_LENGTH; ++i)
+            printf("%02x", md[i]);
+        printf("\n");
+    }
+#endif
+    return 0;
+}
diff -up openssl-1.0.2i/crypto/fips/fips_test_suite.c.fips openssl-1.0.2i/crypto/fips/fips_test_suite.c
--- openssl-1.0.2i/crypto/fips/fips_test_suite.c.fips	2016-09-22 13:35:57.020221066 +0200
+++ openssl-1.0.2i/crypto/fips/fips_test_suite.c	2016-09-22 13:35:57.019221043 +0200
@@ -0,0 +1,639 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ *
+ * This command is intended as a test driver for the FIPS-140 testing
+ * lab performing FIPS-140 validation.  It demonstrates the use of the
+ * OpenSSL library ito perform a variety of common cryptographic
+ * functions.  A power-up self test is demonstrated by deliberately
+ * pointing to an invalid executable hash
+ *
+ * Contributed by Steve Marquess.
+ *
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include <openssl/des.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#ifndef OPENSSL_FIPS
+int main(int argc, char *argv[])
+{
+    printf("No FIPS support\n");
+    return (0);
+}
+#else
+
+# include <openssl/fips.h>
+# include "fips_utl.h"
+
+/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
+*/
+static int FIPS_aes_test(void)
+{
+    int ret = 0;
+    unsigned char pltmp[16];
+    unsigned char citmp[16];
+    unsigned char key[16] =
+        { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+    unsigned char plaintext[16] = "etaonrishdlcu";
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+    if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 1) <= 0)
+        goto err;
+    EVP_Cipher(&ctx, citmp, plaintext, 16);
+    if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 0) <= 0)
+        goto err;
+    EVP_Cipher(&ctx, pltmp, citmp, 16);
+    if (memcmp(pltmp, plaintext, 16))
+        goto err;
+    ret = 1;
+ err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    return ret;
+}
+
+static int FIPS_des3_test(void)
+{
+    int ret = 0;
+    unsigned char pltmp[8];
+    unsigned char citmp[8];
+    unsigned char key[] =
+        { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+        19, 20, 21, 22, 23, 24
+    };
+    unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
+    EVP_CIPHER_CTX ctx;
+    EVP_CIPHER_CTX_init(&ctx);
+    if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 1) <= 0)
+        goto err;
+    EVP_Cipher(&ctx, citmp, plaintext, 8);
+    if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 0) <= 0)
+        goto err;
+    EVP_Cipher(&ctx, pltmp, citmp, 8);
+    if (memcmp(pltmp, plaintext, 8))
+        goto err;
+    ret = 1;
+ err:
+    EVP_CIPHER_CTX_cleanup(&ctx);
+    return ret;
+}
+
+/*
+ * DSA: generate keys and sign, verify input plaintext.
+ */
+static int FIPS_dsa_test(int bad)
+{
+    DSA *dsa = NULL;
+    EVP_PKEY pk;
+    unsigned char dgst[] = "etaonrishdlc";
+    unsigned char buf[60];
+    unsigned int slen;
+    int r = 0;
+    EVP_MD_CTX mctx;
+
+    ERR_clear_error();
+    EVP_MD_CTX_init(&mctx);
+    dsa = DSA_new();
+    if (!dsa)
+        goto end;
+    if (!DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL))
+        goto end;
+    if (!DSA_generate_key(dsa))
+        goto end;
+    if (bad)
+        BN_add_word(dsa->pub_key, 1);
+
+    pk.type = EVP_PKEY_DSA;
+    pk.pkey.dsa = dsa;
+
+    if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
+        goto end;
+    if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1))
+        goto end;
+    if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+        goto end;
+
+    if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
+        goto end;
+    if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1))
+        goto end;
+    r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
+ end:
+    EVP_MD_CTX_cleanup(&mctx);
+    if (dsa)
+        DSA_free(dsa);
+    if (r != 1)
+        return 0;
+    return 1;
+}
+
+/*
+ * RSA: generate keys and sign, verify input plaintext.
+ */
+static int FIPS_rsa_test(int bad)
+{
+    RSA *key;
+    unsigned char input_ptext[] = "etaonrishdlc";
+    unsigned char buf[256];
+    unsigned int slen;
+    BIGNUM *bn;
+    EVP_MD_CTX mctx;
+    EVP_PKEY pk;
+    int r = 0;
+
+    ERR_clear_error();
+    EVP_MD_CTX_init(&mctx);
+    key = RSA_new();
+    bn = BN_new();
+    if (!key || !bn)
+        return 0;
+    BN_set_word(bn, 65537);
+    if (!RSA_generate_key_ex(key, 1024, bn, NULL))
+        return 0;
+    BN_free(bn);
+    if (bad)
+        BN_add_word(key->n, 1);
+
+    pk.type = EVP_PKEY_RSA;
+    pk.pkey.rsa = key;
+
+    if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL))
+        goto end;
+    if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
+        goto end;
+    if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+        goto end;
+
+    if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL))
+        goto end;
+    if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
+        goto end;
+    r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
+ end:
+    EVP_MD_CTX_cleanup(&mctx);
+    if (key)
+        RSA_free(key);
+    if (r != 1)
+        return 0;
+    return 1;
+}
+
+/* SHA1: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_sha1_test()
+{
+    unsigned char digest[SHA_DIGEST_LENGTH] =
+        { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a,
+0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
+    unsigned char str[] = "etaonrishd";
+
+    unsigned char md[SHA_DIGEST_LENGTH];
+
+    ERR_clear_error();
+    if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha1(), NULL))
+        return 0;
+    if (memcmp(md, digest, sizeof(md)))
+        return 0;
+    return 1;
+}
+
+/* SHA256: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_sha256_test()
+{
+    unsigned char digest[SHA256_DIGEST_LENGTH] =
+        { 0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9,
+0x68, 0xc0, 0xea, 0x40, 0x91,
+        0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6,
+            0x50, 0x4f, 0x47, 0x57
+    };
+    unsigned char str[] = "etaonrishd";
+
+    unsigned char md[SHA256_DIGEST_LENGTH];
+
+    ERR_clear_error();
+    if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha256(), NULL))
+        return 0;
+    if (memcmp(md, digest, sizeof(md)))
+        return 0;
+    return 1;
+}
+
+/* SHA512: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_sha512_test()
+{
+    unsigned char digest[SHA512_DIGEST_LENGTH] =
+        { 0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f,
+0x94, 0x71, 0x64, 0x28, 0xca,
+        0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2,
+            0xd0, 0xe7, 0x0b, 0x94, 0x4a,
+        0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f,
+            0x24, 0xb1, 0xd9, 0x40, 0x22,
+        0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6,
+            0xeb, 0x2d, 0x42, 0x1d, 0xa3
+    };
+    unsigned char str[] = "etaonrishd";
+
+    unsigned char md[SHA512_DIGEST_LENGTH];
+
+    ERR_clear_error();
+    if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha512(), NULL))
+        return 0;
+    if (memcmp(md, digest, sizeof(md)))
+        return 0;
+    return 1;
+}
+
+/* HMAC-SHA1: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_hmac_sha1_test()
+{
+    unsigned char key[] = "etaonrishd";
+    unsigned char iv[] = "Sample text";
+    unsigned char kaval[EVP_MAX_MD_SIZE] =
+        { 0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea,
+0x56, 0x1b, 0x61, 0x2e, 0x70,
+        0xb2, 0xfb, 0xec, 0xc6
+    };
+
+    unsigned char out[EVP_MAX_MD_SIZE];
+    unsigned int outlen;
+
+    ERR_clear_error();
+    if (!HMAC
+        (EVP_sha1(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out, &outlen))
+        return 0;
+    if (memcmp(out, kaval, outlen))
+        return 0;
+    return 1;
+}
+
+/* HMAC-SHA224: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_hmac_sha224_test()
+{
+    unsigned char key[] = "etaonrishd";
+    unsigned char iv[] = "Sample text";
+    unsigned char kaval[EVP_MAX_MD_SIZE] =
+        { 0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe,
+0x1c, 0xb2, 0xf0, 0x20, 0x35,
+        0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19
+    };
+
+    unsigned char out[EVP_MAX_MD_SIZE];
+    unsigned int outlen;
+
+    ERR_clear_error();
+    if (!HMAC
+        (EVP_sha224(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
+         &outlen))
+        return 0;
+    if (memcmp(out, kaval, outlen))
+        return 0;
+    return 1;
+}
+
+/* HMAC-SHA256: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_hmac_sha256_test()
+{
+    unsigned char key[] = "etaonrishd";
+    unsigned char iv[] = "Sample text";
+    unsigned char kaval[EVP_MAX_MD_SIZE] =
+        { 0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36,
+0x02, 0xf5, 0x72, 0x33, 0x87,
+        0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee,
+            0x51, 0xff, 0xda, 0x24, 0xf4
+    };
+
+    unsigned char out[EVP_MAX_MD_SIZE];
+    unsigned int outlen;
+
+    ERR_clear_error();
+    if (!HMAC
+        (EVP_sha256(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
+         &outlen))
+        return 0;
+    if (memcmp(out, kaval, outlen))
+        return 0;
+    return 1;
+}
+
+/* HMAC-SHA384: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_hmac_sha384_test()
+{
+    unsigned char key[] = "etaonrishd";
+    unsigned char iv[] = "Sample text";
+    unsigned char kaval[EVP_MAX_MD_SIZE] =
+        { 0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08,
+0x26, 0x99, 0xef, 0x3b, 0x10,
+        0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b,
+            0xac, 0xb0, 0x07, 0x39, 0x08,
+        0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3,
+            0xf3, 0xb8, 0x9b, 0x88, 0x1c
+    };
+
+    unsigned char out[EVP_MAX_MD_SIZE];
+    unsigned int outlen;
+
+    ERR_clear_error();
+    if (!HMAC
+        (EVP_sha384(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
+         &outlen))
+        return 0;
+    if (memcmp(out, kaval, outlen))
+        return 0;
+    return 1;
+}
+
+/* HMAC-SHA512: generate hash of known digest value and compare to known
+   precomputed correct hash
+*/
+static int FIPS_hmac_sha512_test()
+{
+    unsigned char key[] = "etaonrishd";
+    unsigned char iv[] = "Sample text";
+    unsigned char kaval[EVP_MAX_MD_SIZE] =
+        { 0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3,
+0x77, 0x59, 0x85, 0xa9, 0xe6,
+        0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1,
+            0xad, 0x7e, 0x24, 0xca, 0xb1,
+        0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52,
+            0x6b, 0x61, 0x7f, 0xeb, 0x9c,
+        0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96,
+            0x3d, 0xa6, 0xd9, 0x2a, 0x53
+    };
+
+    unsigned char out[EVP_MAX_MD_SIZE];
+    unsigned int outlen;
+
+    ERR_clear_error();
+    if (!HMAC
+        (EVP_sha512(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out,
+         &outlen))
+        return 0;
+    if (memcmp(out, kaval, outlen))
+        return 0;
+    return 1;
+}
+
+/* DH: generate shared parameters
+*/
+static int dh_test()
+{
+    DH *dh;
+    ERR_clear_error();
+    dh = FIPS_dh_new();
+    if (!dh)
+        return 0;
+    if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
+        return 0;
+    FIPS_dh_free(dh);
+    return 1;
+}
+
+/* Zeroize
+*/
+static int Zeroize()
+{
+    RSA *key;
+    BIGNUM *bn;
+    unsigned char userkey[16] =
+        { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f,
+0x83, 0x02, 0xb1, 0x09, 0x68 };
+    int i, n;
+
+    key = FIPS_rsa_new();
+    bn = BN_new();
+    if (!key || !bn)
+        return 0;
+    BN_set_word(bn, 65537);
+    if (!RSA_generate_key_ex(key, 1024, bn, NULL))
+        return 0;
+    BN_free(bn);
+
+    n = BN_num_bytes(key->d);
+    printf(" Generated %d byte RSA private key\n", n);
+    printf("\tBN key before overwriting:\n");
+    do_bn_print(stdout, key->d);
+    BN_rand(key->d, n * 8, -1, 0);
+    printf("\tBN key after overwriting:\n");
+    do_bn_print(stdout, key->d);
+
+    printf("\tchar buffer key before overwriting: \n\t\t");
+    for (i = 0; i < sizeof(userkey); i++)
+        printf("%02x", userkey[i]);
+    printf("\n");
+    RAND_bytes(userkey, sizeof userkey);
+    printf("\tchar buffer key after overwriting: \n\t\t");
+    for (i = 0; i < sizeof(userkey); i++)
+        printf("%02x", userkey[i]);
+    printf("\n");
+
+    return 1;
+}
+
+static int Error;
+const char *Fail(const char *msg)
+{
+    do_print_errors();
+    Error++;
+    return msg;
+}
+
+int main(int argc, char **argv)
+{
+
+    int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
+    int bad_rsa = 0, bad_dsa = 0;
+    int do_rng_stick = 0;
+    int no_exit = 0;
+
+    printf("\tFIPS-mode test application\n\n");
+
+    /* Load entropy from external file, if any */
+    RAND_load_file(".rnd", 1024);
+
+    if (argv[1]) {
+        /* Corrupted KAT tests */
+        if (!strcmp(argv[1], "aes")) {
+            FIPS_corrupt_aes();
+            printf("AES encryption/decryption with corrupted KAT...\n");
+        } else if (!strcmp(argv[1], "des")) {
+            FIPS_corrupt_des();
+            printf("DES3-ECB encryption/decryption with corrupted KAT...\n");
+        } else if (!strcmp(argv[1], "dsa")) {
+            FIPS_corrupt_dsa();
+            printf
+                ("DSA key generation and signature validation with corrupted KAT...\n");
+        } else if (!strcmp(argv[1], "rsa")) {
+            FIPS_corrupt_rsa();
+            printf
+                ("RSA key generation and signature validation with corrupted KAT...\n");
+        } else if (!strcmp(argv[1], "rsakey")) {
+            printf
+                ("RSA key generation and signature validation with corrupted key...\n");
+            bad_rsa = 1;
+            no_exit = 1;
+        } else if (!strcmp(argv[1], "rsakeygen")) {
+            do_corrupt_rsa_keygen = 1;
+            no_exit = 1;
+            printf
+                ("RSA key generation and signature validation with corrupted keygen...\n");
+        } else if (!strcmp(argv[1], "dsakey")) {
+            printf
+                ("DSA key generation and signature validation with corrupted key...\n");
+            bad_dsa = 1;
+            no_exit = 1;
+        } else if (!strcmp(argv[1], "dsakeygen")) {
+            do_corrupt_dsa_keygen = 1;
+            no_exit = 1;
+            printf
+                ("DSA key generation and signature validation with corrupted keygen...\n");
+        } else if (!strcmp(argv[1], "sha1")) {
+            FIPS_corrupt_sha1();
+            printf("SHA-1 hash with corrupted KAT...\n");
+        } else if (!strcmp(argv[1], "rng")) {
+            FIPS_corrupt_rng();
+        } else if (!strcmp(argv[1], "rngstick")) {
+            do_rng_stick = 1;
+            no_exit = 1;
+            printf("RNG test with stuck continuous test...\n");
+        } else {
+            printf("Bad argument \"%s\"\n", argv[1]);
+            exit(1);
+        }
+        if (!no_exit) {
+            if (!FIPS_mode_set(1)) {
+                do_print_errors();
+                printf("Power-up self test failed\n");
+                exit(1);
+            }
+            printf("Power-up self test successful\n");
+            exit(0);
+        }
+    }
+
+    /* Non-Approved cryptographic operation
+     */
+    printf("1. Non-Approved cryptographic operation test...\n");
+    printf("\ta. Included algorithm (D-H)...");
+    printf(dh_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* Power-up self test
+     */
+    ERR_clear_error();
+    printf("2. Automatic power-up self test...");
+    if (!FIPS_mode_set(1)) {
+        do_print_errors();
+        printf(Fail("FAILED!\n"));
+        exit(1);
+    }
+    printf("successful\n");
+    if (do_corrupt_dsa_keygen)
+        FIPS_corrupt_dsa_keygen();
+    if (do_corrupt_rsa_keygen)
+        FIPS_corrupt_rsa_keygen();
+    if (do_rng_stick)
+        FIPS_rng_stick();
+
+    /* AES encryption/decryption
+     */
+    printf("3. AES encryption/decryption...");
+    printf(FIPS_aes_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* RSA key generation and encryption/decryption
+     */
+    printf("4. RSA key generation and encryption/decryption...");
+    printf(FIPS_rsa_test(bad_rsa) ? "successful\n" : Fail("FAILED!\n"));
+
+    /* DES-CBC encryption/decryption
+     */
+    printf("5. DES-ECB encryption/decryption...");
+    printf(FIPS_des3_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* DSA key generation and signature validation
+     */
+    printf("6. DSA key generation and signature validation...");
+    printf(FIPS_dsa_test(bad_dsa) ? "successful\n" : Fail("FAILED!\n"));
+
+    /* SHA-1 hash
+     */
+    printf("7a. SHA-1 hash...");
+    printf(FIPS_sha1_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* SHA-256 hash
+     */
+    printf("7b. SHA-256 hash...");
+    printf(FIPS_sha256_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* SHA-512 hash
+     */
+    printf("7c. SHA-512 hash...");
+    printf(FIPS_sha512_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* HMAC-SHA-1 hash
+     */
+    printf("7d. HMAC-SHA-1 hash...");
+    printf(FIPS_hmac_sha1_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* HMAC-SHA-224 hash
+     */
+    printf("7e. HMAC-SHA-224 hash...");
+    printf(FIPS_hmac_sha224_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* HMAC-SHA-256 hash
+     */
+    printf("7f. HMAC-SHA-256 hash...");
+    printf(FIPS_hmac_sha256_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* HMAC-SHA-384 hash
+     */
+    printf("7g. HMAC-SHA-384 hash...");
+    printf(FIPS_hmac_sha384_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* HMAC-SHA-512 hash
+     */
+    printf("7h. HMAC-SHA-512 hash...");
+    printf(FIPS_hmac_sha512_test()? "successful\n" : Fail("FAILED!\n"));
+
+    /* Non-Approved cryptographic operation
+     */
+    printf("8. Non-Approved cryptographic operation test...\n");
+    printf("\ta. Included algorithm (D-H)...");
+    printf(dh_test()? "successful as expected\n"
+           : Fail("failed INCORRECTLY!\n"));
+
+    /* Zeroization
+     */
+    printf("9. Zero-ization...\n");
+    printf(Zeroize()? "\tsuccessful as expected\n"
+           : Fail("\tfailed INCORRECTLY!\n"));
+
+    printf("\nAll tests completed with %d errors\n", Error);
+    return Error ? 1 : 0;
+}
+
+#endif
diff -up openssl-1.0.2i/crypto/fips/Makefile.fips openssl-1.0.2i/crypto/fips/Makefile
--- openssl-1.0.2i/crypto/fips/Makefile.fips	2016-09-22 13:35:57.020221066 +0200
+++ openssl-1.0.2i/crypto/fips/Makefile	2016-09-22 13:35:57.020221066 +0200
@@ -0,0 +1,341 @@
+#
+# OpenSSL/crypto/fips/Makefile
+#
+
+DIR=	fips
+TOP=	../..
+CC=	cc
+INCLUDES=
+CFLAG=-g
+MAKEFILE=	Makefile
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=fips_test_suite.c fips_randtest.c
+APPS=
+
+PROGRAM= fips_standalone_hmac
+EXE= $(PROGRAM)$(EXE_EXT)
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_aes_selftest.c fips_des_selftest.c fips_hmac_selftest.c fips_rand_selftest.c \
+    fips_rsa_selftest.c fips_sha_selftest.c fips.c fips_dsa_selftest.c  fips_rand.c \
+    fips_rsa_x931g.c fips_post.c fips_drbg_ctr.c fips_drbg_hash.c fips_drbg_hmac.c \
+    fips_drbg_lib.c fips_drbg_rand.c fips_drbg_selftest.c fips_rand_lib.c \
+    fips_cmac_selftest.c fips_enc.c fips_md.c
+
+LIBOBJ=fips_aes_selftest.o fips_des_selftest.o fips_hmac_selftest.o fips_rand_selftest.o \
+    fips_rsa_selftest.o fips_sha_selftest.o fips.o fips_dsa_selftest.o  fips_rand.o \
+    fips_rsa_x931g.o fips_post.o fips_drbg_ctr.o fips_drbg_hash.o fips_drbg_hmac.o \
+    fips_drbg_lib.o fips_drbg_rand.o fips_drbg_selftest.o fips_rand_lib.o \
+    fips_cmac_selftest.o fips_enc.o fips_md.o
+
+LIBCRYPTO=-L.. -lcrypto
+
+SRC= $(LIBSRC) fips_standalone_hmac.c
+
+EXHEADER= fips.h fips_rand.h
+HEADER=	$(EXHEADER)
+
+ALL=    $(GENERAL) $(SRC) $(HEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib exe
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+exe:	$(EXE)
+
+files:
+	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+$(EXE): $(PROGRAM).o
+	FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha256.o; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../sha/$$i" ; done; \
+	for i in $(CPUID_OBJ); do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../$$i" ; done; \
+	$(CC) -o $@ $(CFLAGS) $(PROGRAM).o $$FIPS_SHA_ASM
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+fips.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+fips.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips.o: ../../include/openssl/symhacks.h fips.c fips_locl.h
+fips_aes_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_aes_selftest.o: ../../include/openssl/crypto.h
+fips_aes_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_aes_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_aes_selftest.o: ../../include/openssl/lhash.h
+fips_aes_selftest.o: ../../include/openssl/obj_mac.h
+fips_aes_selftest.o: ../../include/openssl/objects.h
+fips_aes_selftest.o: ../../include/openssl/opensslconf.h
+fips_aes_selftest.o: ../../include/openssl/opensslv.h
+fips_aes_selftest.o: ../../include/openssl/ossl_typ.h
+fips_aes_selftest.o: ../../include/openssl/safestack.h
+fips_aes_selftest.o: ../../include/openssl/stack.h
+fips_aes_selftest.o: ../../include/openssl/symhacks.h fips_aes_selftest.c
+fips_des_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_des_selftest.o: ../../include/openssl/crypto.h
+fips_des_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_des_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_des_selftest.o: ../../include/openssl/lhash.h
+fips_des_selftest.o: ../../include/openssl/obj_mac.h
+fips_des_selftest.o: ../../include/openssl/objects.h
+fips_des_selftest.o: ../../include/openssl/opensslconf.h
+fips_des_selftest.o: ../../include/openssl/opensslv.h
+fips_des_selftest.o: ../../include/openssl/ossl_typ.h
+fips_des_selftest.o: ../../include/openssl/safestack.h
+fips_des_selftest.o: ../../include/openssl/stack.h
+fips_des_selftest.o: ../../include/openssl/symhacks.h fips_des_selftest.c
+fips_drbg_ctr.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_ctr.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_ctr.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h
+fips_drbg_ctr.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_drbg_ctr.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
+fips_drbg_ctr.o: ../../include/openssl/objects.h
+fips_drbg_ctr.o: ../../include/openssl/opensslconf.h
+fips_drbg_ctr.o: ../../include/openssl/opensslv.h
+fips_drbg_ctr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_drbg_ctr.o: ../../include/openssl/safestack.h
+fips_drbg_ctr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_drbg_ctr.o: fips_drbg_ctr.c fips_rand_lcl.h
+fips_drbg_hash.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_hash.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_hash.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h
+fips_drbg_hash.o: ../../include/openssl/fips.h
+fips_drbg_hash.o: ../../include/openssl/fips_rand.h
+fips_drbg_hash.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
+fips_drbg_hash.o: ../../include/openssl/objects.h
+fips_drbg_hash.o: ../../include/openssl/opensslconf.h
+fips_drbg_hash.o: ../../include/openssl/opensslv.h
+fips_drbg_hash.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_drbg_hash.o: ../../include/openssl/safestack.h
+fips_drbg_hash.o: ../../include/openssl/stack.h
+fips_drbg_hash.o: ../../include/openssl/symhacks.h fips_drbg_hash.c
+fips_drbg_hash.o: fips_rand_lcl.h
+fips_drbg_hmac.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_hmac.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h
+fips_drbg_hmac.o: ../../include/openssl/fips.h
+fips_drbg_hmac.o: ../../include/openssl/fips_rand.h
+fips_drbg_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
+fips_drbg_hmac.o: ../../include/openssl/objects.h
+fips_drbg_hmac.o: ../../include/openssl/opensslconf.h
+fips_drbg_hmac.o: ../../include/openssl/opensslv.h
+fips_drbg_hmac.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_drbg_hmac.o: ../../include/openssl/safestack.h
+fips_drbg_hmac.o: ../../include/openssl/stack.h
+fips_drbg_hmac.o: ../../include/openssl/symhacks.h fips_drbg_hmac.c
+fips_drbg_hmac.o: fips_rand_lcl.h
+fips_drbg_lib.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_lib.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_drbg_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_drbg_lib.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_drbg_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_drbg_lib.o: ../../include/openssl/objects.h
+fips_drbg_lib.o: ../../include/openssl/opensslconf.h
+fips_drbg_lib.o: ../../include/openssl/opensslv.h
+fips_drbg_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_drbg_lib.o: ../../include/openssl/safestack.h
+fips_drbg_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_drbg_lib.o: fips_drbg_lib.c fips_locl.h fips_rand_lcl.h
+fips_drbg_rand.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_drbg_rand.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_drbg_rand.o: ../../include/openssl/fips_rand.h
+fips_drbg_rand.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_drbg_rand.o: ../../include/openssl/obj_mac.h
+fips_drbg_rand.o: ../../include/openssl/objects.h
+fips_drbg_rand.o: ../../include/openssl/opensslconf.h
+fips_drbg_rand.o: ../../include/openssl/opensslv.h
+fips_drbg_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_drbg_rand.o: ../../include/openssl/safestack.h
+fips_drbg_rand.o: ../../include/openssl/stack.h
+fips_drbg_rand.o: ../../include/openssl/symhacks.h fips_drbg_rand.c
+fips_drbg_rand.o: fips_rand_lcl.h
+fips_drbg_selftest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_selftest.o: ../../include/openssl/bio.h
+fips_drbg_selftest.o: ../../include/openssl/crypto.h
+fips_drbg_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_drbg_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_drbg_selftest.o: ../../include/openssl/fips_rand.h
+fips_drbg_selftest.o: ../../include/openssl/hmac.h
+fips_drbg_selftest.o: ../../include/openssl/lhash.h
+fips_drbg_selftest.o: ../../include/openssl/obj_mac.h
+fips_drbg_selftest.o: ../../include/openssl/objects.h
+fips_drbg_selftest.o: ../../include/openssl/opensslconf.h
+fips_drbg_selftest.o: ../../include/openssl/opensslv.h
+fips_drbg_selftest.o: ../../include/openssl/ossl_typ.h
+fips_drbg_selftest.o: ../../include/openssl/rand.h
+fips_drbg_selftest.o: ../../include/openssl/safestack.h
+fips_drbg_selftest.o: ../../include/openssl/stack.h
+fips_drbg_selftest.o: ../../include/openssl/symhacks.h fips_drbg_selftest.c
+fips_drbg_selftest.o: fips_drbg_selftest.h fips_locl.h fips_rand_lcl.h
+fips_dsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_selftest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_selftest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dsa_selftest.o: ../../include/openssl/obj_mac.h
+fips_dsa_selftest.o: ../../include/openssl/objects.h
+fips_dsa_selftest.o: ../../include/openssl/opensslconf.h
+fips_dsa_selftest.o: ../../include/openssl/opensslv.h
+fips_dsa_selftest.o: ../../include/openssl/ossl_typ.h
+fips_dsa_selftest.o: ../../include/openssl/safestack.h
+fips_dsa_selftest.o: ../../include/openssl/stack.h
+fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c
+fips_dsa_selftest.o: fips_locl.h
+fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_hmac_selftest.o: ../../include/openssl/crypto.h
+fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_hmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_hmac_selftest.o: ../../include/openssl/hmac.h
+fips_hmac_selftest.o: ../../include/openssl/lhash.h
+fips_hmac_selftest.o: ../../include/openssl/obj_mac.h
+fips_hmac_selftest.o: ../../include/openssl/objects.h
+fips_hmac_selftest.o: ../../include/openssl/opensslconf.h
+fips_hmac_selftest.o: ../../include/openssl/opensslv.h
+fips_hmac_selftest.o: ../../include/openssl/ossl_typ.h
+fips_hmac_selftest.o: ../../include/openssl/safestack.h
+fips_hmac_selftest.o: ../../include/openssl/stack.h
+fips_hmac_selftest.o: ../../include/openssl/symhacks.h fips_hmac_selftest.c
+fips_post.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_post.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_post.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_post.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_post.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_post.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_post.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_post.o: ../../include/openssl/opensslconf.h
+fips_post.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_post.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+fips_post.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_post.o: ../../include/openssl/symhacks.h fips_locl.h fips_post.c
+fips_rand.o: ../../e_os.h ../../include/openssl/aes.h
+fips_rand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_rand.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_rand.o: ../../include/openssl/opensslconf.h
+fips_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+fips_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rand.o: fips_locl.h fips_rand.c
+fips_rand_lib.o: ../../e_os.h ../../include/openssl/aes.h
+fips_rand_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rand_lib.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_rand_lib.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_rand_lib.o: ../../include/openssl/obj_mac.h
+fips_rand_lib.o: ../../include/openssl/objects.h
+fips_rand_lib.o: ../../include/openssl/opensslconf.h
+fips_rand_lib.o: ../../include/openssl/opensslv.h
+fips_rand_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_rand_lib.o: ../../include/openssl/safestack.h
+fips_rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rand_lib.o: fips_rand_lib.c
+fips_rand_selftest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_rand_selftest.o: ../../include/openssl/bio.h
+fips_rand_selftest.o: ../../include/openssl/crypto.h
+fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rand_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rand_selftest.o: ../../include/openssl/fips_rand.h
+fips_rand_selftest.o: ../../include/openssl/hmac.h
+fips_rand_selftest.o: ../../include/openssl/lhash.h
+fips_rand_selftest.o: ../../include/openssl/obj_mac.h
+fips_rand_selftest.o: ../../include/openssl/objects.h
+fips_rand_selftest.o: ../../include/openssl/opensslconf.h
+fips_rand_selftest.o: ../../include/openssl/opensslv.h
+fips_rand_selftest.o: ../../include/openssl/ossl_typ.h
+fips_rand_selftest.o: ../../include/openssl/rand.h
+fips_rand_selftest.o: ../../include/openssl/safestack.h
+fips_rand_selftest.o: ../../include/openssl/stack.h
+fips_rand_selftest.o: ../../include/openssl/symhacks.h fips_locl.h
+fips_rand_selftest.o: fips_rand_selftest.c
+fips_rsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsa_selftest.o: ../../include/openssl/lhash.h
+fips_rsa_selftest.o: ../../include/openssl/obj_mac.h
+fips_rsa_selftest.o: ../../include/openssl/objects.h
+fips_rsa_selftest.o: ../../include/openssl/opensslconf.h
+fips_rsa_selftest.o: ../../include/openssl/opensslv.h
+fips_rsa_selftest.o: ../../include/openssl/ossl_typ.h
+fips_rsa_selftest.o: ../../include/openssl/rsa.h
+fips_rsa_selftest.o: ../../include/openssl/safestack.h
+fips_rsa_selftest.o: ../../include/openssl/stack.h
+fips_rsa_selftest.o: ../../include/openssl/symhacks.h fips_rsa_selftest.c
+fips_rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_x931g.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_rsa_x931g.o: ../../include/openssl/opensslconf.h
+fips_rsa_x931g.o: ../../include/openssl/opensslv.h
+fips_rsa_x931g.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsa_x931g.o: ../../include/openssl/safestack.h
+fips_rsa_x931g.o: ../../include/openssl/stack.h
+fips_rsa_x931g.o: ../../include/openssl/symhacks.h fips_rsa_x931g.c
+fips_sha_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_sha_selftest.o: ../../include/openssl/crypto.h
+fips_sha_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_sha_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_sha_selftest.o: ../../include/openssl/lhash.h
+fips_sha_selftest.o: ../../include/openssl/obj_mac.h
+fips_sha_selftest.o: ../../include/openssl/objects.h
+fips_sha_selftest.o: ../../include/openssl/opensslconf.h
+fips_sha_selftest.o: ../../include/openssl/opensslv.h
+fips_sha_selftest.o: ../../include/openssl/ossl_typ.h
+fips_sha_selftest.o: ../../include/openssl/safestack.h
+fips_sha_selftest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_sha_selftest.o: ../../include/openssl/symhacks.h fips_sha_selftest.c
diff -up openssl-1.0.2i/crypto/hmac/hmac.c.fips openssl-1.0.2i/crypto/hmac/hmac.c
--- openssl-1.0.2i/crypto/hmac/hmac.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/hmac/hmac.c	2016-09-22 13:35:57.020221066 +0200
@@ -89,12 +89,6 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const vo
             EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS);
             return 0;
         }
-        /*
-         * Other algorithm blocking will be done in FIPS_cmac_init, via
-         * FIPS_hmac_init_ex().
-         */
-        if (!impl && !ctx->i_ctx.engine)
-            return FIPS_hmac_init_ex(ctx, key, len, md, NULL);
     }
 #endif
     /* If we are changing MD then we must have a key */
@@ -111,6 +105,13 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const vo
     }
 
     if (key != NULL) {
+#ifdef OPENSSL_FIPS
+        if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS)
+            && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
+                || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
+                || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)))
+            goto err;
+#endif
         reset = 1;
         j = EVP_MD_block_size(md);
         OPENSSL_assert(j <= (int)sizeof(ctx->key));
@@ -164,10 +165,6 @@ int HMAC_Init(HMAC_CTX *ctx, const void
 
 int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
 {
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !ctx->i_ctx.engine)
-        return FIPS_hmac_update(ctx, data, len);
-#endif
     if (!ctx->md)
         return 0;
 
@@ -178,10 +175,6 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned c
 {
     unsigned int i;
     unsigned char buf[EVP_MAX_MD_SIZE];
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !ctx->i_ctx.engine)
-        return FIPS_hmac_final(ctx, md, len);
-#endif
 
     if (!ctx->md)
         goto err;
@@ -225,12 +218,6 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_C
 
 void HMAC_CTX_cleanup(HMAC_CTX *ctx)
 {
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !ctx->i_ctx.engine) {
-        FIPS_hmac_ctx_cleanup(ctx);
-        return;
-    }
-#endif
     EVP_MD_CTX_cleanup(&ctx->i_ctx);
     EVP_MD_CTX_cleanup(&ctx->o_ctx);
     EVP_MD_CTX_cleanup(&ctx->md_ctx);
diff -up openssl-1.0.2i/crypto/mdc2/mdc2dgst.c.fips openssl-1.0.2i/crypto/mdc2/mdc2dgst.c
--- openssl-1.0.2i/crypto/mdc2/mdc2dgst.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/mdc2/mdc2dgst.c	2016-09-22 13:35:57.020221066 +0200
@@ -76,7 +76,7 @@
                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
 
 static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
-fips_md_init(MDC2)
+nonfips_md_init(MDC2)
 {
     c->num = 0;
     c->pad_type = 1;
diff -up openssl-1.0.2i/crypto/md2/md2_dgst.c.fips openssl-1.0.2i/crypto/md2/md2_dgst.c
--- openssl-1.0.2i/crypto/md2/md2_dgst.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/md2/md2_dgst.c	2016-09-22 13:35:57.020221066 +0200
@@ -62,6 +62,11 @@
 #include <openssl/md2.h>
 #include <openssl/opensslv.h>
 #include <openssl/crypto.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+#include <openssl/err.h>
 
 const char MD2_version[] = "MD2" OPENSSL_VERSION_PTEXT;
 
@@ -119,7 +124,7 @@ const char *MD2_options(void)
         return ("md2(int)");
 }
 
-fips_md_init(MD2)
+nonfips_md_init(MD2)
 {
     c->num = 0;
     memset(c->state, 0, sizeof c->state);
diff -up openssl-1.0.2i/crypto/md4/md4_dgst.c.fips openssl-1.0.2i/crypto/md4/md4_dgst.c
--- openssl-1.0.2i/crypto/md4/md4_dgst.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/md4/md4_dgst.c	2016-09-22 13:35:57.020221066 +0200
@@ -72,7 +72,7 @@ const char MD4_version[] = "MD4" OPENSSL
 #define INIT_DATA_C (unsigned long)0x98badcfeL
 #define INIT_DATA_D (unsigned long)0x10325476L
 
-fips_md_init(MD4)
+nonfips_md_init(MD4)
 {
     memset(c, 0, sizeof(*c));
     c->A = INIT_DATA_A;
diff -up openssl-1.0.2i/crypto/md5/md5_dgst.c.fips openssl-1.0.2i/crypto/md5/md5_dgst.c
--- openssl-1.0.2i/crypto/md5/md5_dgst.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/md5/md5_dgst.c	2016-09-22 13:35:57.020221066 +0200
@@ -72,7 +72,7 @@ const char MD5_version[] = "MD5" OPENSSL
 #define INIT_DATA_C (unsigned long)0x98badcfeL
 #define INIT_DATA_D (unsigned long)0x10325476L
 
-fips_md_init(MD5)
+nonfips_md_init(MD5)
 {
     memset(c, 0, sizeof(*c));
     c->A = INIT_DATA_A;
diff -up openssl-1.0.2i/crypto/o_fips.c.fips openssl-1.0.2i/crypto/o_fips.c
--- openssl-1.0.2i/crypto/o_fips.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/o_fips.c	2016-09-22 13:35:57.020221066 +0200
@@ -80,6 +80,8 @@ int FIPS_mode_set(int r)
 # ifndef FIPS_AUTH_USER_PASS
 #  define FIPS_AUTH_USER_PASS     "Default FIPS Crypto User Password"
 # endif
+    if (r && FIPS_module_mode()) /* can be implicitly initialized by OPENSSL_init() */
+        return 1;
     if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS))
         return 0;
     if (r)
diff -up openssl-1.0.2i/crypto/o_init.c.fips openssl-1.0.2i/crypto/o_init.c
--- openssl-1.0.2i/crypto/o_init.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/o_init.c	2016-09-22 13:38:19.150496906 +0200
@@ -56,8 +56,37 @@
 #include <e_os.h>
 #include <openssl/err.h>
 #ifdef OPENSSL_FIPS
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+# include <errno.h>
+# include <stdlib.h>
 # include <openssl/fips.h>
 # include <openssl/rand.h>
+
+# define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled"
+
+static void init_fips_mode(void)
+{
+    char buf[2] = "0";
+    int fd;
+
+    if (getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) {
+        buf[0] = '1';
+    } else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) {
+        while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR) ;
+        close(fd);
+    }
+    /* Failure reading the fips mode switch file means just not
+     * switching into FIPS mode. We would break too many things
+     * otherwise..
+     */
+
+    if (buf[0] == '1') {
+        FIPS_mode_set(1);
+    }
+}
 #endif
 
 /*
@@ -65,22 +94,26 @@
  * sets FIPS callbacks
  */
 
-void OPENSSL_init(void)
+void OPENSSL_init_library(void)
 {
     static int done = 0;
     if (done)
         return;
     done = 1;
 #ifdef OPENSSL_FIPS
-    FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
-# ifndef OPENSSL_NO_DEPRECATED
-    FIPS_crypto_set_id_callback(CRYPTO_thread_id);
-# endif
-    FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
-    FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
     RAND_init_fips();
+    init_fips_mode();
+    if (!FIPS_mode()) {
+        /* Clean up prematurely set default rand method */
+        RAND_set_rand_method(NULL);
+    }
 #endif
 #if 0
     fprintf(stderr, "Called OPENSSL_init\n");
 #endif
 }
+
+void OPENSSL_init(void)
+{
+    OPENSSL_init_library();
+}
diff -up openssl-1.0.2i/crypto/opensslconf.h.in.fips openssl-1.0.2i/crypto/opensslconf.h.in
--- openssl-1.0.2i/crypto/opensslconf.h.in.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/opensslconf.h.in	2016-09-22 13:35:57.021221089 +0200
@@ -1,5 +1,20 @@
 /* crypto/opensslconf.h.in */
 
+#ifdef OPENSSL_DOING_MAKEDEPEND
+
+/* Include any symbols here that have to be explicitly set to enable a feature
+ * that should be visible to makedepend.
+ *
+ * [Our "make depend" doesn't actually look at this, we use actual build settings
+ * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
+ */
+
+#ifndef OPENSSL_FIPS
+#define OPENSSL_FIPS
+#endif
+
+#endif
+
 /* Generate 80386 code? */
 #undef I386_ONLY
 
diff -up openssl-1.0.2i/crypto/rand/md_rand.c.fips openssl-1.0.2i/crypto/rand/md_rand.c
--- openssl-1.0.2i/crypto/rand/md_rand.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rand/md_rand.c	2016-09-22 13:35:57.021221089 +0200
@@ -391,7 +391,10 @@ int ssleay_rand_bytes(unsigned char *buf
     CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
     crypto_lock_rand = 1;
 
-    if (!initialized) {
+    /* always poll for external entropy in FIPS mode, drbg provides the 
+     * expansion
+     */
+    if (!initialized || FIPS_module_mode()) {
         RAND_poll();
         initialized = 1;
     }
diff -up openssl-1.0.2i/crypto/rand/rand.h.fips openssl-1.0.2i/crypto/rand/rand.h
--- openssl-1.0.2i/crypto/rand/rand.h.fips	2016-09-22 13:35:56.777215465 +0200
+++ openssl-1.0.2i/crypto/rand/rand.h	2016-09-22 13:35:57.021221089 +0200
@@ -133,16 +133,34 @@ void ERR_load_RAND_strings(void);
 /* Error codes for the RAND functions. */
 
 /* Function codes. */
+# define RAND_F_ENG_RAND_GET_RAND_METHOD                  108
+# define RAND_F_FIPS_RAND                                 103
+# define RAND_F_FIPS_RAND_BYTES                           102
+# define RAND_F_FIPS_RAND_SET_DT                          106
+# define RAND_F_FIPS_X931_SET_DT                          106
+# define RAND_F_FIPS_SET_DT                               104
+# define RAND_F_FIPS_SET_PRNG_SEED                        107
+# define RAND_F_FIPS_SET_TEST_MODE                        105
 # define RAND_F_RAND_GET_RAND_METHOD                      101
-# define RAND_F_RAND_INIT_FIPS                            102
+# define RAND_F_RAND_INIT_FIPS                            109
 # define RAND_F_SSLEAY_RAND_BYTES                         100
 
 /* Reason codes. */
-# define RAND_R_DUAL_EC_DRBG_DISABLED                     104
-# define RAND_R_ERROR_INITIALISING_DRBG                   102
-# define RAND_R_ERROR_INSTANTIATING_DRBG                  103
-# define RAND_R_NO_FIPS_RANDOM_METHOD_SET                 101
+# define RAND_R_DUAL_EC_DRBG_DISABLED                     114
+# define RAND_R_ERROR_INITIALISING_DRBG                   112
+# define RAND_R_ERROR_INSTANTIATING_DRBG                  113
+# define RAND_R_NON_FIPS_METHOD                           105
+# define RAND_R_NOT_IN_TEST_MODE                          106
+# define RAND_R_NO_FIPS_RANDOM_METHOD_SET                 111
+# define RAND_R_NO_KEY_SET                                107
+# define RAND_R_PRNG_ASKING_FOR_TOO_MUCH                  101
+# define RAND_R_PRNG_ERROR                                108
+# define RAND_R_PRNG_KEYED                                109
+# define RAND_R_PRNG_NOT_REKEYED                          102
+# define RAND_R_PRNG_NOT_RESEEDED                         103
 # define RAND_R_PRNG_NOT_SEEDED                           100
+# define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY              110
+# define RAND_R_PRNG_STUCK                                104
 
 #ifdef  __cplusplus
 }
diff -up openssl-1.0.2i/crypto/ripemd/rmd_dgst.c.fips openssl-1.0.2i/crypto/ripemd/rmd_dgst.c
--- openssl-1.0.2i/crypto/ripemd/rmd_dgst.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/ripemd/rmd_dgst.c	2016-09-22 13:35:57.021221089 +0200
@@ -70,7 +70,7 @@ void ripemd160_block_x86(RIPEMD160_CTX *
 void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num);
 #endif
 
-fips_md_init(RIPEMD160)
+nonfips_md_init(RIPEMD160)
 {
     memset(c, 0, sizeof(*c));
     c->A = RIPEMD160_A;
diff -up openssl-1.0.2i/crypto/rsa/rsa_crpt.c.fips openssl-1.0.2i/crypto/rsa/rsa_crpt.c
--- openssl-1.0.2i/crypto/rsa/rsa_crpt.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa_crpt.c	2016-09-22 13:35:57.021221089 +0200
@@ -89,9 +89,9 @@ int RSA_private_encrypt(int flen, const
                         unsigned char *to, RSA *rsa, int padding)
 {
 #ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
-        && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
-        RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+    if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+        RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT,
+               RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
         return -1;
     }
 #endif
@@ -115,9 +115,9 @@ int RSA_public_decrypt(int flen, const u
                        RSA *rsa, int padding)
 {
 #ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
-        && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
-        RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+    if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
+        RSAerr(RSA_F_RSA_PUBLIC_DECRYPT,
+               RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
         return -1;
     }
 #endif
diff -up openssl-1.0.2i/crypto/rsa/rsa_eay.c.fips openssl-1.0.2i/crypto/rsa/rsa_eay.c
--- openssl-1.0.2i/crypto/rsa/rsa_eay.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa_eay.c	2016-09-22 13:35:57.022221112 +0200
@@ -114,6 +114,10 @@
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
 #include <openssl/rand.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
 
 #ifndef RSA_NULL
 
@@ -140,7 +144,7 @@ static RSA_METHOD rsa_pkcs1_eay_meth = {
                                  * if e == 3 */
     RSA_eay_init,
     RSA_eay_finish,
-    0,                          /* flags */
+    RSA_FLAG_FIPS_METHOD,       /* flags */
     NULL,
     0,                          /* rsa_sign */
     0,                          /* rsa_verify */
@@ -160,6 +164,22 @@ static int RSA_eay_public_encrypt(int fl
     unsigned char *buf = NULL;
     BN_CTX *ctx = NULL;
 
+# ifdef OPENSSL_FIPS
+    if (FIPS_mode()) {
+        if (FIPS_selftest_failed()) {
+            FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,
+                    FIPS_R_FIPS_SELFTEST_FAILED);
+            goto err;
+        }
+
+        if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+            && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) {
+            RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+            return -1;
+        }
+    }
+# endif
+
     if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
         RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
         return -1;
@@ -361,6 +381,22 @@ static int RSA_eay_private_encrypt(int f
     BIGNUM *unblind = NULL;
     BN_BLINDING *blinding = NULL;
 
+# ifdef OPENSSL_FIPS
+    if (FIPS_mode()) {
+        if (FIPS_selftest_failed()) {
+            FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,
+                    FIPS_R_FIPS_SELFTEST_FAILED);
+            return -1;
+        }
+
+        if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+            && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) {
+            RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+            return -1;
+        }
+    }
+# endif
+
     if ((ctx = BN_CTX_new()) == NULL)
         goto err;
     BN_CTX_start(ctx);
@@ -497,6 +533,22 @@ static int RSA_eay_private_decrypt(int f
     BIGNUM *unblind = NULL;
     BN_BLINDING *blinding = NULL;
 
+# ifdef OPENSSL_FIPS
+    if (FIPS_mode()) {
+        if (FIPS_selftest_failed()) {
+            FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,
+                    FIPS_R_FIPS_SELFTEST_FAILED);
+            return -1;
+        }
+
+        if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+            && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) {
+            RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+            return -1;
+        }
+    }
+# endif
+
     if ((ctx = BN_CTX_new()) == NULL)
         goto err;
     BN_CTX_start(ctx);
@@ -623,6 +675,22 @@ static int RSA_eay_public_decrypt(int fl
     unsigned char *buf = NULL;
     BN_CTX *ctx = NULL;
 
+# ifdef OPENSSL_FIPS
+    if (FIPS_mode()) {
+        if (FIPS_selftest_failed()) {
+            FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,
+                    FIPS_R_FIPS_SELFTEST_FAILED);
+            goto err;
+        }
+
+        if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)
+            && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) {
+            RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+            return -1;
+        }
+    }
+# endif
+
     if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
         RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
         return -1;
@@ -886,6 +954,9 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c
 
 static int RSA_eay_init(RSA *rsa)
 {
+# ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+# endif
     rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE;
     return (1);
 }
diff -up openssl-1.0.2i/crypto/rsa/rsa_err.c.fips openssl-1.0.2i/crypto/rsa/rsa_err.c
--- openssl-1.0.2i/crypto/rsa/rsa_err.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa_err.c	2016-09-22 13:35:57.022221112 +0200
@@ -136,6 +136,8 @@ static ERR_STRING_DATA RSA_str_functs[]
     {ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"},
     {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
     {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
+    {ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"},
+    {ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"},
     {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
     {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),
      "RSA_sign_ASN1_OCTET_STRING"},
diff -up openssl-1.0.2i/crypto/rsa/rsa_gen.c.fips openssl-1.0.2i/crypto/rsa/rsa_gen.c
--- openssl-1.0.2i/crypto/rsa/rsa_gen.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa_gen.c	2016-09-22 13:35:57.022221112 +0200
@@ -69,8 +69,80 @@
 #include <openssl/rsa.h>
 #ifdef OPENSSL_FIPS
 # include <openssl/fips.h>
-extern int FIPS_rsa_x931_generate_key_ex(RSA *rsa, int bits, BIGNUM *e,
-                                         BN_GENCB *cb);
+# include <openssl/err.h>
+# include <openssl/evp.h>
+
+static int fips_rsa_pairwise_fail = 0;
+
+void FIPS_corrupt_rsa_keygen(void)
+{
+    fips_rsa_pairwise_fail = 1;
+}
+
+int fips_check_rsa(RSA *rsa)
+{
+    const unsigned char tbs[] = "RSA Pairwise Check Data";
+    unsigned char *ctbuf = NULL, *ptbuf = NULL;
+    int len, ret = 0;
+    EVP_PKEY *pk;
+
+    if ((pk = EVP_PKEY_new()) == NULL)
+        goto err;
+
+    EVP_PKEY_set1_RSA(pk, rsa);
+
+    /* Perform pairwise consistency signature test */
+    if (!fips_pkey_signature_test(pk, tbs, -1,
+                                  NULL, 0, EVP_sha1(),
+                                  EVP_MD_CTX_FLAG_PAD_PKCS1, NULL)
+        || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(),
+                                     EVP_MD_CTX_FLAG_PAD_X931, NULL)
+        || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(),
+                                     EVP_MD_CTX_FLAG_PAD_PSS, NULL))
+        goto err;
+    /* Now perform pairwise consistency encrypt/decrypt test */
+    ctbuf = OPENSSL_malloc(RSA_size(rsa));
+    if (!ctbuf)
+        goto err;
+
+    len =
+        RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa,
+                           RSA_PKCS1_PADDING);
+    if (len <= 0)
+        goto err;
+    /* Check ciphertext doesn't match plaintext */
+    if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len))
+        goto err;
+    ptbuf = OPENSSL_malloc(RSA_size(rsa));
+
+    if (!ptbuf)
+        goto err;
+    len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING);
+    if (len != (sizeof(tbs) - 1))
+        goto err;
+    if (memcmp(ptbuf, tbs, len))
+        goto err;
+
+    ret = 1;
+
+    if (!ptbuf)
+        goto err;
+
+ err:
+    if (ret == 0) {
+        fips_set_selftest_fail();
+        FIPSerr(FIPS_F_FIPS_CHECK_RSA, FIPS_R_PAIRWISE_TEST_FAILED);
+    }
+
+    if (ctbuf)
+        OPENSSL_free(ctbuf);
+    if (ptbuf)
+        OPENSSL_free(ptbuf);
+    if (pk)
+        EVP_PKEY_free(pk);
+
+    return ret;
+}
 #endif
 
 static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
@@ -86,7 +158,7 @@ static int rsa_builtin_keygen(RSA *rsa,
 int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
 {
 #ifdef OPENSSL_FIPS
-    if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+    if (FIPS_module_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
         && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) {
         RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD);
         return 0;
@@ -94,10 +166,6 @@ int RSA_generate_key_ex(RSA *rsa, int bi
 #endif
     if (rsa->meth->rsa_keygen)
         return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
-#ifdef OPENSSL_FIPS
-    if (FIPS_mode())
-        return FIPS_rsa_x931_generate_key_ex(rsa, bits, e_value, cb);
-#endif
     return rsa_builtin_keygen(rsa, bits, e_value, cb);
 }
 
@@ -110,6 +178,20 @@ static int rsa_builtin_keygen(RSA *rsa,
     int bitsp, bitsq, ok = -1, n = 0;
     BN_CTX *ctx = NULL;
 
+#ifdef OPENSSL_FIPS
+    if (FIPS_module_mode()) {
+        if (FIPS_selftest_failed()) {
+            FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_FIPS_SELFTEST_FAILED);
+            return 0;
+        }
+
+        if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) {
+            FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_KEY_TOO_SHORT);
+            return 0;
+        }
+    }
+#endif
+
     ctx = BN_CTX_new();
     if (ctx == NULL)
         goto err;
@@ -235,6 +317,16 @@ static int rsa_builtin_keygen(RSA *rsa,
     if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx))
         goto err;
 
+#ifdef OPENSSL_FIPS
+    if (FIPS_module_mode()) {
+        if (fips_rsa_pairwise_fail)
+            BN_add_word(rsa->n, 1);
+
+        if (!fips_check_rsa(rsa))
+            goto err;
+    }
+#endif
+
     ok = 1;
  err:
     if (ok == -1) {
diff -up openssl-1.0.2i/crypto/rsa/rsa.h.fips openssl-1.0.2i/crypto/rsa/rsa.h
--- openssl-1.0.2i/crypto/rsa/rsa.h.fips	2016-09-22 13:35:56.906218439 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa.h	2016-09-22 13:35:57.022221112 +0200
@@ -168,6 +168,8 @@ struct rsa_st {
 #  define OPENSSL_RSA_MAX_MODULUS_BITS   16384
 # endif
 
+# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024
+
 # ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
 #  define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
 # endif
@@ -329,6 +331,13 @@ RSA *RSA_generate_key(int bits, unsigned
 
 /* New version */
 int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
+                       BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2,
+                       const BIGNUM *Xp, const BIGNUM *Xq1,
+                       const BIGNUM *Xq2, const BIGNUM *Xq,
+                       const BIGNUM *e, BN_GENCB *cb);
+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e,
+                             BN_GENCB *cb);
 
 int RSA_check_key(const RSA *);
         /* next 4 return -1 on error */
@@ -538,7 +547,7 @@ void ERR_load_RSA_strings(void);
 # define RSA_F_RSA_ALGOR_TO_MD                            157
 # define RSA_F_RSA_BUILTIN_KEYGEN                         129
 # define RSA_F_RSA_CHECK_KEY                              123
-# define RSA_F_RSA_CMS_DECRYPT                            158
+# define RSA_F_RSA_CMS_DECRYPT                            258
 # define RSA_F_RSA_EAY_PRIVATE_DECRYPT                    101
 # define RSA_F_RSA_EAY_PRIVATE_ENCRYPT                    102
 # define RSA_F_RSA_EAY_PUBLIC_DECRYPT                     103
@@ -559,7 +568,7 @@ void ERR_load_RSA_strings(void);
 # define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP                 121
 # define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1            160
 # define RSA_F_RSA_PADDING_ADD_PKCS1_PSS                  125
-# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1             148
+# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1             158
 # define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1               108
 # define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2               109
 # define RSA_F_RSA_PADDING_ADD_SSLV23                     110
@@ -573,21 +582,23 @@ void ERR_load_RSA_strings(void);
 # define RSA_F_RSA_PADDING_CHECK_X931                     128
 # define RSA_F_RSA_PRINT                                  115
 # define RSA_F_RSA_PRINT_FP                               116
-# define RSA_F_RSA_PRIVATE_DECRYPT                        150
-# define RSA_F_RSA_PRIVATE_ENCRYPT                        151
+# define RSA_F_RSA_PRIVATE_DECRYPT                        157
+# define RSA_F_RSA_PRIVATE_ENCRYPT                        148
 # define RSA_F_RSA_PRIV_DECODE                            137
 # define RSA_F_RSA_PRIV_ENCODE                            138
 # define RSA_F_RSA_PSS_TO_CTX                             162
-# define RSA_F_RSA_PUBLIC_DECRYPT                         152
+# define RSA_F_RSA_PUBLIC_DECRYPT                         149
 # define RSA_F_RSA_PUBLIC_ENCRYPT                         153
 # define RSA_F_RSA_PUB_DECODE                             139
 # define RSA_F_RSA_SETUP_BLINDING                         136
+# define RSA_F_RSA_SET_DEFAULT_METHOD                     150
+# define RSA_F_RSA_SET_METHOD                             151
 # define RSA_F_RSA_SIGN                                   117
 # define RSA_F_RSA_SIGN_ASN1_OCTET_STRING                 118
 # define RSA_F_RSA_VERIFY                                 119
 # define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING               120
 # define RSA_F_RSA_VERIFY_PKCS1_PSS                       126
-# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1                  149
+# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1                  152
 
 /* Reason codes. */
 # define RSA_R_ALGORITHM_MISMATCH                         100
@@ -620,21 +631,22 @@ void ERR_load_RSA_strings(void);
 # define RSA_R_INVALID_OAEP_PARAMETERS                    162
 # define RSA_R_INVALID_PADDING                            138
 # define RSA_R_INVALID_PADDING_MODE                       141
-# define RSA_R_INVALID_PSS_PARAMETERS                     149
+# define RSA_R_INVALID_PSS_PARAMETERS                     157
 # define RSA_R_INVALID_PSS_SALTLEN                        146
-# define RSA_R_INVALID_SALT_LENGTH                        150
+# define RSA_R_INVALID_SALT_LENGTH                        158
 # define RSA_R_INVALID_TRAILER                            139
 # define RSA_R_INVALID_X931_DIGEST                        142
 # define RSA_R_IQMP_NOT_INVERSE_OF_Q                      126
 # define RSA_R_KEY_SIZE_TOO_SMALL                         120
 # define RSA_R_LAST_OCTET_INVALID                         134
 # define RSA_R_MODULUS_TOO_LARGE                          105
-# define RSA_R_NON_FIPS_RSA_METHOD                        157
+# define RSA_R_NON_FIPS_RSA_METHOD                        149
+# define RSA_R_NON_FIPS_METHOD                            149
 # define RSA_R_NO_PUBLIC_EXPONENT                         140
 # define RSA_R_NULL_BEFORE_BLOCK_MISSING                  113
 # define RSA_R_N_DOES_NOT_EQUAL_P_Q                       127
 # define RSA_R_OAEP_DECODING_ERROR                        121
-# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE         158
+# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE         150
 # define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   148
 # define RSA_R_PADDING_CHECK_FAILED                       114
 # define RSA_R_PKCS_DECODING_ERROR                        159
diff -up openssl-1.0.2i/crypto/rsa/rsa_lib.c.fips openssl-1.0.2i/crypto/rsa/rsa_lib.c
--- openssl-1.0.2i/crypto/rsa/rsa_lib.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa_lib.c	2016-09-22 13:35:57.022221112 +0200
@@ -84,23 +84,22 @@ RSA *RSA_new(void)
 
 void RSA_set_default_method(const RSA_METHOD *meth)
 {
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) {
+        RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
+        return;
+    }
+#endif
     default_RSA_meth = meth;
 }
 
 const RSA_METHOD *RSA_get_default_method(void)
 {
     if (default_RSA_meth == NULL) {
-#ifdef OPENSSL_FIPS
-        if (FIPS_mode())
-            return FIPS_rsa_pkcs1_ssleay();
-        else
-            return RSA_PKCS1_SSLeay();
-#else
-# ifdef RSA_NULL
+#ifdef RSA_NULL
         default_RSA_meth = RSA_null_method();
-# else
+#else
         default_RSA_meth = RSA_PKCS1_SSLeay();
-# endif
 #endif
     }
 
@@ -119,6 +118,12 @@ int RSA_set_method(RSA *rsa, const RSA_M
      * to deal with which ENGINE it comes from.
      */
     const RSA_METHOD *mtmp;
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) {
+        RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_METHOD);
+        return 0;
+    }
+#endif
     mtmp = rsa->meth;
     if (mtmp->finish)
         mtmp->finish(rsa);
@@ -166,6 +171,17 @@ RSA *RSA_new_method(ENGINE *engine)
         }
     }
 #endif
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD)) {
+        RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD);
+# ifndef OPENSSL_NO_ENGINE
+        if (ret->engine)
+            ENGINE_finish(ret->engine);
+# endif
+        OPENSSL_free(ret);
+        return NULL;
+    }
+#endif
 
     ret->pad = 0;
     ret->version = 0;
@@ -184,7 +200,7 @@ RSA *RSA_new_method(ENGINE *engine)
     ret->blinding = NULL;
     ret->mt_blinding = NULL;
     ret->bignum_data = NULL;
-    ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
+    ret->flags = ret->meth->flags;
     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) {
 #ifndef OPENSSL_NO_ENGINE
         if (ret->engine)
diff -up openssl-1.0.2i/crypto/rsa/rsa_pmeth.c.fips openssl-1.0.2i/crypto/rsa/rsa_pmeth.c
--- openssl-1.0.2i/crypto/rsa/rsa_pmeth.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa_pmeth.c	2016-09-22 13:35:57.022221112 +0200
@@ -228,20 +228,6 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *c
             RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH);
             return -1;
         }
-#ifdef OPENSSL_FIPS
-        if (ret > 0) {
-            unsigned int slen;
-            ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md,
-                                       rctx->pad_mode,
-                                       rctx->saltlen,
-                                       rctx->mgf1md, sig, &slen);
-            if (ret > 0)
-                *siglen = slen;
-            else
-                *siglen = 0;
-            return ret;
-        }
-#endif
 
         if (EVP_MD_type(rctx->md) == NID_mdc2) {
             unsigned int sltmp;
@@ -359,17 +345,6 @@ static int pkey_rsa_verify(EVP_PKEY_CTX
     }
 #endif
     if (rctx->md) {
-#ifdef OPENSSL_FIPS
-        if (rv > 0) {
-            return FIPS_rsa_verify_digest(rsa,
-                                          tbs, tbslen,
-                                          rctx->md,
-                                          rctx->pad_mode,
-                                          rctx->saltlen,
-                                          rctx->mgf1md, sig, siglen);
-
-        }
-#endif
         if (rctx->pad_mode == RSA_PKCS1_PADDING)
             return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
                               sig, siglen, rsa);
diff -up openssl-1.0.2i/crypto/rsa/rsa_sign.c.fips openssl-1.0.2i/crypto/rsa/rsa_sign.c
--- openssl-1.0.2i/crypto/rsa/rsa_sign.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/rsa/rsa_sign.c	2016-09-22 13:35:57.023221135 +0200
@@ -132,7 +132,10 @@ int RSA_sign(int type, const unsigned ch
         i2d_X509_SIG(&sig, &p);
         s = tmps;
     }
-    i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
+    /* NB: call underlying method directly to avoid FIPS blocking */
+    i = rsa->meth->rsa_priv_enc ? rsa->meth->rsa_priv_enc(i, s, sigret, rsa,
+                                                          RSA_PKCS1_PADDING) :
+        0;
     if (i <= 0)
         ret = 0;
     else
@@ -188,8 +191,10 @@ int int_rsa_verify(int dtype, const unsi
     }
 
     if ((dtype == NID_md5_sha1) && rm) {
-        i = RSA_public_decrypt((int)siglen,
-                               sigbuf, rm, rsa, RSA_PKCS1_PADDING);
+        i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen,
+                                                            sigbuf, rm, rsa,
+                                                            RSA_PKCS1_PADDING)
+            : 0;
         if (i <= 0)
             return 0;
         *prm_len = i;
@@ -205,7 +210,11 @@ int int_rsa_verify(int dtype, const unsi
         RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
         goto err;
     }
-    i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
+    /* NB: call underlying method directly to avoid FIPS blocking */
+    i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen, sigbuf,
+                                                        s, rsa,
+                                                        RSA_PKCS1_PADDING) :
+        0;
 
     if (i <= 0)
         goto err;
diff -up openssl-1.0.2i/crypto/sha/sha.h.fips openssl-1.0.2i/crypto/sha/sha.h
--- openssl-1.0.2i/crypto/sha/sha.h.fips	2016-09-22 13:35:56.699213667 +0200
+++ openssl-1.0.2i/crypto/sha/sha.h	2016-09-22 13:35:57.023221135 +0200
@@ -105,9 +105,6 @@ typedef struct SHAstate_st {
 } SHA_CTX;
 
 # ifndef OPENSSL_NO_SHA0
-#  ifdef OPENSSL_FIPS
-int private_SHA_Init(SHA_CTX *c);
-#  endif
 int SHA_Init(SHA_CTX *c);
 int SHA_Update(SHA_CTX *c, const void *data, size_t len);
 int SHA_Final(unsigned char *md, SHA_CTX *c);
@@ -115,9 +112,6 @@ unsigned char *SHA(const unsigned char *
 void SHA_Transform(SHA_CTX *c, const unsigned char *data);
 # endif
 # ifndef OPENSSL_NO_SHA1
-#  ifdef OPENSSL_FIPS
-int private_SHA1_Init(SHA_CTX *c);
-#  endif
 int SHA1_Init(SHA_CTX *c);
 int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
 int SHA1_Final(unsigned char *md, SHA_CTX *c);
@@ -139,10 +133,6 @@ typedef struct SHA256state_st {
 } SHA256_CTX;
 
 # ifndef OPENSSL_NO_SHA256
-#  ifdef OPENSSL_FIPS
-int private_SHA224_Init(SHA256_CTX *c);
-int private_SHA256_Init(SHA256_CTX *c);
-#  endif
 int SHA224_Init(SHA256_CTX *c);
 int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
 int SHA224_Final(unsigned char *md, SHA256_CTX *c);
@@ -192,10 +182,6 @@ typedef struct SHA512state_st {
 # endif
 
 # ifndef OPENSSL_NO_SHA512
-#  ifdef OPENSSL_FIPS
-int private_SHA384_Init(SHA512_CTX *c);
-int private_SHA512_Init(SHA512_CTX *c);
-#  endif
 int SHA384_Init(SHA512_CTX *c);
 int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
 int SHA384_Final(unsigned char *md, SHA512_CTX *c);
diff -up openssl-1.0.2i/crypto/sha/sha_locl.h.fips openssl-1.0.2i/crypto/sha/sha_locl.h
--- openssl-1.0.2i/crypto/sha/sha_locl.h.fips	2016-09-22 13:35:56.702213737 +0200
+++ openssl-1.0.2i/crypto/sha/sha_locl.h	2016-09-22 13:35:57.023221135 +0200
@@ -123,11 +123,14 @@ void sha1_block_data_order(SHA_CTX *c, c
 #define INIT_DATA_h4 0xc3d2e1f0UL
 
 #ifdef SHA_0
-fips_md_init(SHA)
+nonfips_md_init(SHA)
 #else
 fips_md_init_ctx(SHA1, SHA)
 #endif
 {
+#if defined(SHA_1) && defined(OPENSSL_FIPS)
+    FIPS_selftest_check();
+#endif
     memset(c, 0, sizeof(*c));
     c->h0 = INIT_DATA_h0;
     c->h1 = INIT_DATA_h1;
diff -up openssl-1.0.2i/crypto/sha/sha256.c.fips openssl-1.0.2i/crypto/sha/sha256.c
--- openssl-1.0.2i/crypto/sha/sha256.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/sha/sha256.c	2016-09-22 13:35:57.023221135 +0200
@@ -12,12 +12,19 @@
 
 # include <openssl/crypto.h>
 # include <openssl/sha.h>
+# ifdef OPENSSL_FIPS
+#  include <openssl/fips.h>
+# endif
+
 # include <openssl/opensslv.h>
 
 const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT;
 
 fips_md_init_ctx(SHA224, SHA256)
 {
+# ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+# endif
     memset(c, 0, sizeof(*c));
     c->h[0] = 0xc1059ed8UL;
     c->h[1] = 0x367cd507UL;
@@ -33,6 +40,9 @@ fips_md_init_ctx(SHA224, SHA256)
 
 fips_md_init(SHA256)
 {
+# ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+# endif
     memset(c, 0, sizeof(*c));
     c->h[0] = 0x6a09e667UL;
     c->h[1] = 0xbb67ae85UL;
diff -up openssl-1.0.2i/crypto/sha/sha512.c.fips openssl-1.0.2i/crypto/sha/sha512.c
--- openssl-1.0.2i/crypto/sha/sha512.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/sha/sha512.c	2016-09-22 13:35:57.023221135 +0200
@@ -5,6 +5,10 @@
  * ====================================================================
  */
 #include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
 /*-
  * IMPLEMENTATION NOTES.
@@ -62,6 +66,9 @@ const char SHA512_version[] = "SHA-512"
 
 fips_md_init_ctx(SHA384, SHA512)
 {
+# ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+# endif
     c->h[0] = U64(0xcbbb9d5dc1059ed8);
     c->h[1] = U64(0x629a292a367cd507);
     c->h[2] = U64(0x9159015a3070dd17);
@@ -80,6 +87,9 @@ fips_md_init_ctx(SHA384, SHA512)
 
 fips_md_init(SHA512)
 {
+# ifdef OPENSSL_FIPS
+    FIPS_selftest_check();
+# endif
     c->h[0] = U64(0x6a09e667f3bcc908);
     c->h[1] = U64(0xbb67ae8584caa73b);
     c->h[2] = U64(0x3c6ef372fe94f82b);
diff -up openssl-1.0.2i/crypto/whrlpool/wp_dgst.c.fips openssl-1.0.2i/crypto/whrlpool/wp_dgst.c
--- openssl-1.0.2i/crypto/whrlpool/wp_dgst.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/crypto/whrlpool/wp_dgst.c	2016-09-22 13:35:57.023221135 +0200
@@ -56,7 +56,7 @@
 #include <openssl/crypto.h>
 #include <string.h>
 
-fips_md_init(WHIRLPOOL)
+nonfips_md_init(WHIRLPOOL)
 {
     memset(c, 0, sizeof(*c));
     return (1);
diff -up openssl-1.0.2i/Makefile.org.fips openssl-1.0.2i/Makefile.org
--- openssl-1.0.2i/Makefile.org.fips	2016-09-22 13:35:56.996220513 +0200
+++ openssl-1.0.2i/Makefile.org	2016-09-22 13:35:57.023221135 +0200
@@ -138,6 +138,9 @@ FIPSCANLIB=
 
 BASEADDR=
 
+# Non-empty if FIPS enabled
+FIPS=
+
 DIRS=   crypto ssl engines apps test tools
 ENGDIRS= ccgost
 SHLIBDIRS= crypto ssl
@@ -150,7 +153,7 @@ SDIRS=  \
 	bn ec rsa dsa ecdsa dh ecdh dso engine \
 	buffer bio stack lhash rand err \
 	evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
-	cms pqueue ts jpake srp store cmac
+	cms pqueue ts jpake srp store cmac fips
 # keep in mind that the above list is adjusted by ./Configure
 # according to no-xxx arguments...
 
@@ -241,6 +244,7 @@ BUILDENV=	LC_ALL=C PLATFORM='$(PLATFORM)
 		FIPSLIBDIR='${FIPSLIBDIR}'			\
 		FIPSDIR='${FIPSDIR}'				\
 		FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}"	\
+		FIPS="$${FIPS:-$(FIPS)}"	\
 		THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
 # MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
 # which in turn eliminates ambiguities in variable treatment with -e.
diff -up openssl-1.0.2i/ssl/ssl_algs.c.fips openssl-1.0.2i/ssl/ssl_algs.c
--- openssl-1.0.2i/ssl/ssl_algs.c.fips	2016-09-22 12:23:06.000000000 +0200
+++ openssl-1.0.2i/ssl/ssl_algs.c	2016-09-22 13:35:57.024221158 +0200
@@ -64,6 +64,11 @@
 int SSL_library_init(void)
 {
 
+#ifdef OPENSSL_FIPS
+    OPENSSL_init_library();
+    if (!FIPS_mode()) {
+#endif
+
 #ifndef OPENSSL_NO_DES
     EVP_add_cipher(EVP_des_cbc());
     EVP_add_cipher(EVP_des_ede3_cbc());
@@ -142,6 +147,48 @@ int SSL_library_init(void)
     EVP_add_digest(EVP_sha());
     EVP_add_digest(EVP_dss());
 #endif
+#ifdef OPENSSL_FIPS
+    } else {
+# ifndef OPENSSL_NO_DES
+        EVP_add_cipher(EVP_des_ede3_cbc());
+# endif
+# ifndef OPENSSL_NO_AES
+        EVP_add_cipher(EVP_aes_128_cbc());
+        EVP_add_cipher(EVP_aes_192_cbc());
+        EVP_add_cipher(EVP_aes_256_cbc());
+        EVP_add_cipher(EVP_aes_128_gcm());
+        EVP_add_cipher(EVP_aes_256_gcm());
+# endif
+# ifndef OPENSSL_NO_MD5
+        /* needed even in the FIPS mode for TLS MAC */
+        EVP_add_digest(EVP_md5());
+        EVP_add_digest_alias(SN_md5, "ssl2-md5");
+        EVP_add_digest_alias(SN_md5, "ssl3-md5");
+# endif
+# ifndef OPENSSL_NO_SHA
+        EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
+        EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
+        EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
+# endif
+# ifndef OPENSSL_NO_SHA256
+        EVP_add_digest(EVP_sha224());
+        EVP_add_digest(EVP_sha256());
+# endif
+# ifndef OPENSSL_NO_SHA512
+        EVP_add_digest(EVP_sha384());
+        EVP_add_digest(EVP_sha512());
+# endif
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA)
+        EVP_add_digest(EVP_dss1()); /* DSA with sha1 */
+        EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2);
+        EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1");
+        EVP_add_digest_alias(SN_dsaWithSHA1, "dss1");
+# endif
+# ifndef OPENSSL_NO_ECDSA
+        EVP_add_digest(EVP_ecdsa());
+# endif
+    }
+#endif
 #ifndef OPENSSL_NO_COMP
     /*
      * This will initialise the built-in compression algorithms. The value