X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fdsa%2Fdsa_ossl.c;h=edaee5987772b078b0f4274406c7e08f7486ed2f;hb=fda29b6db038716e4409068798646c6db042e552;hp=33ac3e130e3dfd1677c847dfcf7c8f6e2b553c9f;hpb=20818e00fd718d961ce861e384de768be1bca36f;p=oweals%2Fopenssl.git diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 33ac3e130e..edaee59877 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -58,6 +58,8 @@ /* Original version from Steven Schoch */ +#define OPENSSL_FIPSAPI + #include #include "cryptlib.h" #include @@ -70,7 +72,10 @@ #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, BIGNUM **rp); +static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp, + const unsigned char *dgst, int dlen); static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); static int dsa_init(DSA *dsa); @@ -79,7 +84,7 @@ static int dsa_finish(DSA *dsa); static DSA_METHOD openssl_dsa_meth = { "OpenSSL DSA method", dsa_do_sign, -dsa_sign_setup, +dsa_sign_setup_no_digest, dsa_do_verify, NULL, /* dsa_mod_exp, */ NULL, /* dsa_bn_mod_exp, */ @@ -148,11 +153,14 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) return NULL; } - if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + if (FIPS_module_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; } + if (!fips_check_dsa_prng(dsa, 0, 0)) + goto err; #endif BN_init(&m); @@ -166,21 +174,13 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) s=BN_new(); if (s == NULL) goto err; - - /* reject a excessive digest length (currently at most - * dsa-with-SHA256 is supported) */ - if (dlen > SHA256_DIGEST_LENGTH) - { - reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; - goto err; - } - ctx=BN_CTX_new(); if (ctx == NULL) goto err; redo: if ((dsa->kinv == NULL) || (dsa->r == NULL)) { - if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err; + if (!dsa_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen)) + goto err; } else { @@ -239,7 +239,14 @@ err: return(ret); } -static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp) { + return dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0); +} + +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp, + const unsigned char *dgst, int dlen) { BN_CTX *ctx; BIGNUM k,kq,*K,*kinv=NULL,*r=NULL; @@ -265,8 +272,22 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) /* Get random k */ do - if (!BN_rand_range(&k, dsa->q)) goto err; - while (BN_is_zero(&k)); + { +#ifndef OPENSSL_NO_SHA512 + if (dgst != NULL) + { + /* We calculate k from SHA512(private_key + H(message) + * + random). This protects the private key from a weak + * PRNG. */ + if (!BN_generate_dsa_nonce(&k, dsa->q, dsa->priv_key, dgst, + dlen, ctx)) + goto err; + } + else +#endif + if (!BN_rand_range(&k, dsa->q)) goto err; + } while (BN_is_zero(&k)); + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { BN_set_flags(&k, BN_FLG_CONSTTIME); @@ -358,7 +379,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, return -1; } - if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + if (FIPS_module_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; @@ -370,15 +392,6 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE); return -1; } - - /* reject a excessive digest length (currently at most - * dsa-with-SHA256 is supported) */ - if (dgst_len > SHA256_DIGEST_LENGTH) - { - DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return -1; - } - BN_init(&u1); BN_init(&u2); BN_init(&t1);