* [including the GNU Public Licence.]
*/
-#ifndef OPENSSL_NO_SHA
+#define OPENSSL_FIPSAPI
+
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
+#ifndef OPENSSL_NO_SHA
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/rand.h>
+#ifdef OPENSSL_FIPS
+
+#include <openssl/fips.h>
+#include <openssl/evp.h>
+
+static int fips_dsa_pairwise_fail = 0;
+
+void FIPS_corrupt_dsa_keygen(void)
+ {
+ fips_dsa_pairwise_fail = 1;
+ }
+
+static int fips_check_dsa(DSA *dsa)
+ {
+ EVP_PKEY pk;
+ unsigned char tbs[] = "DSA Pairwise Check Data";
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+
+ if (!fips_pkey_signature_test(&pk, tbs, -1,
+ NULL, 0, EVP_sha1(), 0, NULL))
+ {
+ FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
+ fips_set_selftest_fail();
+ return 0;
+ }
+ return 1;
+ }
+
+#endif
+
+static int dsa_builtin_keygen(DSA *dsa);
+
int DSA_generate_key(DSA *dsa)
+ {
+ if(dsa->meth->dsa_keygen)
+ return dsa->meth->dsa_keygen(dsa);
+ return dsa_builtin_keygen(dsa);
+ }
+
+static int dsa_builtin_keygen(DSA *dsa)
{
int ok=0;
BN_CTX *ctx=NULL;
BIGNUM *pub_key=NULL,*priv_key=NULL;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && (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;
if (dsa->priv_key == NULL)
}
else
pub_key=dsa->pub_key;
+
+ {
+ BIGNUM local_prk;
+ BIGNUM *prk;
- if (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err;
+ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ BN_init(&local_prk);
+ prk = &local_prk;
+ BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+ }
+ else
+ prk = priv_key;
+
+ if (!BN_mod_exp(pub_key,dsa->g,prk,dsa->p,ctx)) goto err;
+ }
dsa->priv_key=priv_key;
dsa->pub_key=pub_key;
+#ifdef OPENSSL_FIPS
+ if (fips_dsa_pairwise_fail)
+ BN_add_word(dsa->pub_key, 1);
+ if(!fips_check_dsa(dsa))
+ {
+ dsa->pub_key = NULL;
+ dsa->priv_key = NULL;
+ goto err;
+ }
+#endif
ok=1;
err: