File openssl-fips__0020_rng-seeding.patch of Package compat-openssl098.1339

diff -rNU 20 ../openssl-0.9.8j-o/crypto/rand/rand_lcl.h ./crypto/rand/rand_lcl.h
--- ../openssl-0.9.8j-o/crypto/rand/rand_lcl.h	2008-09-16 13:50:05.000000000 +0200
+++ ./crypto/rand/rand_lcl.h	2011-08-09 14:06:21.000000000 +0200
@@ -95,41 +95,42 @@
  * 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).
  *
  */
 
 #ifndef HEADER_RAND_LCL_H
 #define HEADER_RAND_LCL_H
 
-#define ENTROPY_NEEDED 32  /* require 256 bits = 32 bytes of randomness */
+/* #define ENTROPY_NEEDED 32 */  /* require 256 bits = 32 bytes of randomness */
+#define ENTROPY_NEEDED 48 /* for FIPS */
 
 
 #if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
 #define USE_SHA1_RAND
 #elif !defined(OPENSSL_NO_MD5)
 #define USE_MD5_RAND
 #elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
 #define USE_MDC2_RAND
 #elif !defined(OPENSSL_NO_MD2)
 #define USE_MD2_RAND
 #else
 #error No message digest algorithm available
 #endif
 #endif
 
 #include <openssl/evp.h>
 #define MD_Update(a,b,c)	EVP_DigestUpdate(a,b,c)
 #define	MD_Final(a,b)		EVP_DigestFinal_ex(a,b,NULL)
 #if defined(USE_MD5_RAND)
diff -rNU 20 ../openssl-0.9.8j-o/fips/fips.c ./fips/fips.c
--- ../openssl-0.9.8j-o/fips/fips.c	2008-09-16 12:12:09.000000000 +0200
+++ ./fips/fips.c	2011-08-09 14:06:21.000000000 +0200
@@ -286,56 +286,56 @@
 	    fips_selftest_fail = 1;
 	    ret = 0;
 	    goto end;
 	    }
 
 	if(!FIPS_check_incore_fingerprint())
 	    {
 	    fips_selftest_fail = 1;
 	    ret = 0;
 	    goto end;
 	    }
 
 	/* Perform RNG KAT before seeding */
 	if (!FIPS_selftest_rng())
 	    {
 	    fips_selftest_fail = 1;
 	    ret = 0;
 	    goto end;
 	    }
 
+	/* now switch into FIPS mode */
+	fips_set_rand_check(FIPS_rand_method());
+	RAND_set_rand_method(FIPS_rand_method());
+
 	/* automagically seed PRNG if not already seeded */
 	if(!FIPS_rand_status())
 	    {
-	    if(RAND_bytes(buf,sizeof buf) <= 0)
+	    RAND_poll();
+	    if (!FIPS_rand_status())
 		{
 		fips_selftest_fail = 1;
 		ret = 0;
 		goto end;
 		}
-	    FIPS_rand_set_key(buf,32);
-	    FIPS_rand_seed(buf+32,16);
 	    }
 
-	/* now switch into FIPS mode */
-	fips_set_rand_check(FIPS_rand_method());
-	RAND_set_rand_method(FIPS_rand_method());
 	if(FIPS_selftest())
 	    fips_set_mode(1);
 	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;
     }
 
diff -rNU 20 ../openssl-0.9.8j-o/fips/rand/fips_rand.c ./fips/rand/fips_rand.c
--- ../openssl-0.9.8j-o/fips/rand/fips_rand.c	2008-09-16 12:12:18.000000000 +0200
+++ ./fips/rand/fips_rand.c	2011-08-09 14:06:21.000000000 +0200
@@ -138,41 +138,52 @@
 		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, FIPS_RAND_SIZE_T seedlen)
 	{
 	int i;
 	if (!ctx->keyed)
-		return 0;
+		{
+		FIPS_RAND_SIZE_T keylen = 16;
+
+		if (seedlen - keylen < AES_BLOCK_LENGTH)
+			return 0;
+		if (seedlen - keylen - 8 >= AES_BLOCK_LENGTH)
+			keylen += 8;
+		if (seedlen - keylen - 8 >= AES_BLOCK_LENGTH)
+			keylen += 8;
+		seedlen -= keylen;
+		fips_set_prng_key(ctx, seed+seedlen, keylen);
+		}
 	/* 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)
@@ -259,40 +270,41 @@
 	buf[11] = (unsigned char) ((ctx->counter >> 24) & 0xff);
 
 	ctx->counter++;
 
 
 #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, FIPS_RAND_SIZE_T outlen)
 	{
 	unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH];
 	unsigned char tmp[AES_BLOCK_LENGTH];
 	int i;
+	FIPS_selftest_check();
 	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_dt(ctx);
 		AES_encrypt(ctx->DT, I, &ctx->ks);