X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Fdsa%2Fdsa_ossl.c;h=edaee5987772b078b0f4274406c7e08f7486ed2f;hb=c944f8170358ecce419045b919be604844369e36;hp=4fead07e80f44398788f9a380a537ff3ae49ac2f;hpb=bd31fb21454609b125ade1ad569ebcc2a2b9b73c;p=openssl.git diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 4fead07e80..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 @@ -65,9 +67,15 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#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); @@ -76,13 +84,13 @@ 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, */ dsa_init, dsa_finish, -0, +DSA_FLAG_FIPS_METHOD, NULL, NULL, NULL @@ -136,6 +144,24 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) BN_CTX *ctx=NULL; int reason=ERR_R_BN_LIB; DSA_SIG *ret=NULL; + int noredo = 0; + +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED); + return NULL; + } + + 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); BN_init(&xr); @@ -148,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 { @@ -170,6 +188,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) dsa->kinv=NULL; r=dsa->r; dsa->r=NULL; + noredo = 1; } @@ -185,11 +204,23 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ if (BN_cmp(s,dsa->q) > 0) - BN_sub(s,s,dsa->q); + if (!BN_sub(s,s,dsa->q)) goto err; if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; ret=DSA_SIG_new(); if (ret == NULL) goto err; + /* Redo if r or s is zero as required by FIPS 186-3: this is + * very unlikely. + */ + if (BN_is_zero(r) || BN_is_zero(s)) + { + if (noredo) + { + reason = DSA_R_NEED_NEW_SETUP_VALUES; + goto err; + } + goto redo; + } ret->r = r; ret->s = s; @@ -208,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; @@ -234,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); @@ -320,20 +372,26 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, return -1; } - if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + 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_MODULUS_TOO_LARGE); + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); return -1; } +#endif - /* reject a excessive digest length (currently at most - * dsa-with-SHA256 is supported) */ - if (dgst_len > SHA256_DIGEST_LENGTH) + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { - DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE); return -1; } - BN_init(&u1); BN_init(&u2); BN_init(&t1);