X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=crypto%2Fdsa%2Fdsa_key.c;h=acc34a586513473aa847503c8497edad40f81ef0;hb=a1a5885b6400cbc7475934771e2626caa161c24e;hp=ef87c3e6372e6cf1eb631498c428bedc86e25243;hpb=323f289c480b0a8eb15ed3be2befbcc0f86e8904;p=openssl.git diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index ef87c3e637..acc34a5865 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -56,20 +56,70 @@ * [including the GNU Public Licence.] */ -#ifndef OPENSSL_NO_SHA +#define OPENSSL_FIPSAPI + #include #include #include "cryptlib.h" +#ifndef OPENSSL_NO_SHA #include #include #include +#ifdef OPENSSL_FIPS + +#include +#include + +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) @@ -89,11 +139,35 @@ int DSA_generate_key(DSA *dsa) } 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: