diff options
Diffstat (limited to 'crypto/dsa')
-rw-r--r-- | crypto/dsa/dsa.h | 32 | ||||
-rw-r--r-- | crypto/dsa/dsa_err.c | 3 | ||||
-rw-r--r-- | crypto/dsa/dsa_ossl.c | 29 | ||||
-rw-r--r-- | crypto/dsa/dsa_sign.c | 9 |
4 files changed, 58 insertions, 15 deletions
diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 408ee11b72..28aa8a3073 100644 --- a/crypto/dsa/dsa.h +++ b/crypto/dsa/dsa.h @@ -91,13 +91,27 @@ #define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 #define DSA_FLAG_CACHE_MONT_P 0x01 -#define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA - * implementation now uses constant time - * modular exponentiation for secret exponents - * by default. This flag causes the - * faster variable sliding window method to - * be used for all exponents. +#define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the + * built-in DSA + * implementation now + * uses constant time + * modular exponentiation + * for secret exponents + * by default. This flag + * causes the faster + * variable sliding + * window method to be + * used for all + * exponents. */ +#define DSA_FLAG_NONCE_FROM_HASH 0x04 /* Causes the DSA nonce + * to be calculated from + * SHA512(private_key + + * H(message) + + * random). This + * strengthens DSA + * against a weak + * PRNG. */ /* If this flag is set the DSA method is FIPS compliant and can be used * in FIPS mode. This is set in the validated module method. If an @@ -133,8 +147,9 @@ struct dsa_method { const char *name; DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa); - int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp); + int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp, + const unsigned char *dgst, int dlen); int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, @@ -338,6 +353,7 @@ void ERR_load_DSA_strings(void); #define DSA_R_MISSING_PARAMETERS 101 #define DSA_R_MODULUS_TOO_LARGE 103 #define DSA_R_NEED_NEW_SETUP_VALUES 110 +#define DSA_R_NONCE_CANNOT_BE_PRECOMPUTED 114 #define DSA_R_NO_PARAMETERS_SET 107 #define DSA_R_PARAMETER_ENCODING_ERROR 105 #define DSA_R_Q_NOT_PRIME 113 diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index a46fade4c6..353d81aa7c 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -1,6 +1,6 @@ /* crypto/dsa/dsa_err.c */ /* ==================================================================== - * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -112,6 +112,7 @@ static ERR_STRING_DATA DSA_str_reasons[]= {ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"}, +{ERR_REASON(DSA_R_NONCE_CANNOT_BE_PRECOMPUTED),"nonce cannot be precomputed"}, {ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"}, {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"}, {ERR_REASON(DSA_R_Q_NOT_PRIME) ,"q not prime"}, diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 485cff0b19..d1f80609b1 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -72,7 +72,9 @@ #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(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); @@ -176,7 +178,8 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) redo: if ((dsa->kinv == NULL) || (dsa->r == NULL)) { - if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err; + if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen)) + goto err; } else { @@ -235,7 +238,9 @@ err: return(ret); } -static int dsa_sign_setup(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) { BN_CTX *ctx; BIGNUM k,kq,*K,*kinv=NULL,*r=NULL; @@ -261,8 +266,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 (dsa->flags & DSA_FLAG_NONCE_FROM_HASH) + { + /* If DSA_FLAG_NONCE_FROM_HASH is set then 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); diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index 599093a4a8..b7e4caab2a 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -72,5 +72,12 @@ DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { - return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); + if (dsa->flags & DSA_FLAG_NONCE_FROM_HASH) + { + /* One cannot precompute the DSA nonce if it is required to + * depend on the message. */ + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NONCE_CANNOT_BE_PRECOMPUTED); + return 0; + } + return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0); } |