19062d
diff -up openssl-1.0.0d/crypto/dsa/dsa_gen.c.cavs openssl-1.0.0d/crypto/dsa/dsa_gen.c
19062d
--- openssl-1.0.0d/crypto/dsa/dsa_gen.c.cavs	2011-05-23 19:59:56.000000000 +0200
19062d
+++ openssl-1.0.0d/crypto/dsa/dsa_gen.c	2011-05-23 22:32:45.000000000 +0200
19062d
@@ -85,6 +85,14 @@
19062d
 #endif
19062d
 #include "dsa_locl.h"
19062d
 
19062d
+#ifndef OPENSSL_FIPS
19062d
+static int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
19062d
+		const EVP_MD *evpmd, unsigned char *seed, int seed_len,
19062d
+		BIGNUM **p_ret, BIGNUM **q_ret, int *counter_ret, BN_GENCB *cb);
19062d
+static int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q,
19062d
+		BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb);
19062d
+#endif
19062d
+
19062d
 int DSA_generate_parameters_ex(DSA *ret, int bits,
19062d
 		const unsigned char *seed_in, int seed_len,
19062d
 		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
19062d
@@ -113,22 +121,26 @@ int DSA_generate_parameters_ex(DSA *ret,
19062d
 		}
19062d
 	}
19062d
 
19062d
+#ifdef OPENSSL_FIPS
19062d
+int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
19062d
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
19062d
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
19062d
+	{
19062d
+	return dsa_builtin_paramgen(ret, bits, qbits,
19062d
+		evpmd, seed_in, seed_len,
19062d
+		counter_ret, h_ret, cb);
19062d
+	}
19062d
+#endif
19062d
+
19062d
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
19062d
 	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
19062d
 	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
19062d
 	{
19062d
 	int ok=0;
19062d
 	unsigned char seed[SHA256_DIGEST_LENGTH];
19062d
-	unsigned char md[SHA256_DIGEST_LENGTH];
19062d
-	unsigned char buf[SHA256_DIGEST_LENGTH];
19062d
-	BIGNUM *r0,*W,*X,*c,*test;
19062d
 	BIGNUM *g=NULL,*q=NULL,*p=NULL;
19062d
-	BN_MONT_CTX *mont=NULL;
19062d
-	int i, k, b, n=0, m=0, qsize = qbits >> 3;
19062d
-	int counter=0;
19062d
-	int r=0;
19062d
+	size_t qsize = qbits >> 3;
19062d
 	BN_CTX *ctx=NULL;
19062d
-	unsigned int h=2;
19062d
 
19062d
 #ifdef OPENSSL_FIPS
19062d
 	if(FIPS_selftest_failed())
19062d
@@ -148,6 +160,65 @@ int dsa_builtin_paramgen(DSA *ret, size_
19062d
 		goto err;
19062d
 		}
19062d
 #endif
19062d
+	if (seed_len && (seed_len < (size_t)qsize))
19062d
+		seed_in = NULL;		/* seed buffer too small -- ignore */
19062d
+	if (seed_len > sizeof(seed)) 
19062d
+		seed_len = sizeof(seed);	/* App. 2.2 of FIPS PUB 186 allows larger SEED,
19062d
+						 * but our internal buffers are restricted to 256 bits*/
19062d
+	if (seed_in != NULL)
19062d
+		memcpy(seed, seed_in, seed_len);
19062d
+	else
19062d
+		seed_len = 0;
19062d
+
19062d
+	if ((ctx=BN_CTX_new()) == NULL)
19062d
+		goto err;
19062d
+
19062d
+	BN_CTX_start(ctx);
19062d
+
19062d
+	if (!FIPS_dsa_generate_pq(ctx, bits, qbits, evpmd,
19062d
+		seed, seed_len, &p, &q, counter_ret, cb))
19062d
+		goto err;
19062d
+
19062d
+	if (!FIPS_dsa_generate_g(ctx, p, q, &g, h_ret, cb))
19062d
+		goto err;
19062d
+
19062d
+	ok=1;
19062d
+err:
19062d
+	if (ok)
19062d
+		{
19062d
+		if(ret->p) BN_free(ret->p);
19062d
+		if(ret->q) BN_free(ret->q);
19062d
+		if(ret->g) BN_free(ret->g);
19062d
+		ret->p=BN_dup(p);
19062d
+		ret->q=BN_dup(q);
19062d
+		ret->g=BN_dup(g);
19062d
+		if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
19062d
+			ok=0;
19062d
+		}
19062d
+	if(ctx)
19062d
+		{
19062d
+		BN_CTX_end(ctx);
19062d
+		BN_CTX_free(ctx);
19062d
+		}
19062d
+	return ok;
19062d
+	}
19062d
+
19062d
+#ifndef OPENSSL_FIPS
19062d
+static
19062d
+#endif
19062d
+int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
19062d
+		const EVP_MD *evpmd, unsigned char *seed, int seed_len,
19062d
+		BIGNUM **p_ret, BIGNUM **q_ret, int *counter_ret, BN_GENCB *cb)
19062d
+	{
19062d
+	int ok=0;
19062d
+	unsigned char md[SHA256_DIGEST_LENGTH];
19062d
+	unsigned char buf[SHA256_DIGEST_LENGTH];
19062d
+	BIGNUM *r0,*W,*X,*c,*test;
19062d
+	BIGNUM *g=NULL,*q=NULL,*p=NULL;
19062d
+	BN_MONT_CTX *mont=NULL;
19062d
+	int i, k, b, n=0, m=0, qsize = qbits >> 3;
19062d
+	int counter=0;
19062d
+	int r=0;
19062d
 
19062d
 	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
19062d
 	    qsize != SHA256_DIGEST_LENGTH)
19062d
@@ -169,28 +240,12 @@ int dsa_builtin_paramgen(DSA *ret, size_
19062d
 
19062d
 	bits = (bits+63)/64*64;
19062d
 
19062d
-	if (seed_len && (seed_len < (size_t)qsize))
19062d
-		seed_in = NULL;		/* seed buffer too small -- ignore */
19062d
-	if (seed_len > (size_t)qsize) 
19062d
-		seed_len = qsize;	/* App. 2.2 of FIPS PUB 186 allows larger SEED,
19062d
-					 * but our internal buffers are restricted to 256 bits*/
19062d
-	if (seed_in != NULL)
19062d
-		memcpy(seed, seed_in, seed_len);
19062d
-
19062d
-	if ((ctx=BN_CTX_new()) == NULL)
19062d
-		goto err;
19062d
-
19062d
-	if ((mont=BN_MONT_CTX_new()) == NULL)
19062d
-		goto err;
19062d
-
19062d
-	BN_CTX_start(ctx);
19062d
 	r0 = BN_CTX_get(ctx);
19062d
-	g = BN_CTX_get(ctx);
19062d
 	W = BN_CTX_get(ctx);
19062d
-	q = BN_CTX_get(ctx);
19062d
+	*q_ret = q = BN_CTX_get(ctx);
19062d
 	X = BN_CTX_get(ctx);
19062d
 	c = BN_CTX_get(ctx);
19062d
-	p = BN_CTX_get(ctx);
19062d
+	*p_ret = p = BN_CTX_get(ctx);
19062d
 	test = BN_CTX_get(ctx);
19062d
 
19062d
 	if (!BN_lshift(test,BN_value_one(),bits-1))
19062d
@@ -312,7 +367,33 @@ end:
19062d
 	if(!BN_GENCB_call(cb, 2, 1))
19062d
 		goto err;
19062d
 
19062d
-	/* We now need to generate g */
19062d
+	ok=1;
19062d
+err:
19062d
+	if (ok)
19062d
+		{
19062d
+		if (counter_ret != NULL) *counter_ret=counter;
19062d
+		}
19062d
+	return ok;
19062d
+	}
19062d
+
19062d
+#ifndef OPENSSL_FIPS
19062d
+static
19062d
+#endif
19062d
+int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q,
19062d
+		BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb)
19062d
+	{
19062d
+	int ok=0;
19062d
+	BIGNUM *r0, *test, *g = NULL;
19062d
+	BN_MONT_CTX *mont;
19062d
+	unsigned int h=2;
19062d
+
19062d
+	if ((mont=BN_MONT_CTX_new()) == NULL)
19062d
+		goto err;
19062d
+
19062d
+	r0 = BN_CTX_get(ctx);
19062d
+	*g_ret = g = BN_CTX_get(ctx);
19062d
+	test = BN_CTX_get(ctx);
19062d
+
19062d
 	/* Set r0=(p-1)/q */
19062d
 	if (!BN_sub(test,p,BN_value_one())) goto err;
19062d
 	if (!BN_div(r0,NULL,test,q,ctx)) goto err;
19062d
@@ -336,25 +417,8 @@ end:
19062d
 err:
19062d
 	if (ok)
19062d
 		{
19062d
-		if(ret->p) BN_free(ret->p);
19062d
-		if(ret->q) BN_free(ret->q);
19062d
-		if(ret->g) BN_free(ret->g);
19062d
-		ret->p=BN_dup(p);
19062d
-		ret->q=BN_dup(q);
19062d
-		ret->g=BN_dup(g);
19062d
-		if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
19062d
-			{
19062d
-			ok=0;
19062d
-			goto err;
19062d
-			}
19062d
-		if (counter_ret != NULL) *counter_ret=counter;
19062d
 		if (h_ret != NULL) *h_ret=h;
19062d
 		}
19062d
-	if(ctx)
19062d
-		{
19062d
-		BN_CTX_end(ctx);
19062d
-		BN_CTX_free(ctx);
19062d
-		}
19062d
 	if (mont != NULL) BN_MONT_CTX_free(mont);
19062d
 	return ok;
19062d
 	}
19062d
diff -up openssl-1.0.0d/crypto/dsa/dsa.h.cavs openssl-1.0.0d/crypto/dsa/dsa.h
19062d
--- openssl-1.0.0d/crypto/dsa/dsa.h.cavs	2011-05-23 19:59:56.000000000 +0200
19062d
+++ openssl-1.0.0d/crypto/dsa/dsa.h	2011-05-23 22:33:33.000000000 +0200
19062d
@@ -266,6 +266,17 @@ int	DSA_print_fp(FILE *bp, const DSA *x,
19062d
 DH *DSA_dup_DH(const DSA *r);
19062d
 #endif
19062d
 
19062d
+#ifdef OPENSSL_FIPS
19062d
+int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
19062d
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
19062d
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
19062d
+int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits,
19062d
+		const EVP_MD *evpmd, unsigned char *seed, int seed_len,
19062d
+		BIGNUM **p_ret, BIGNUM **q_ret, int *counter_ret, BN_GENCB *cb);
19062d
+int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q,
19062d
+		BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb);
19062d
+#endif
19062d
+
19062d
 #define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
19062d
 	EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
19062d
 				EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)