diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h index d7397cae8baf8a21053a5d993cadbbfbe5bdd498..7c23c01c2f7f4e2e8809dcd2f57836ccc2bda74a 100644 --- a/crypto/bn/bn.h +++ b/crypto/bn/bn.h @@ -676,6 +676,10 @@ const BIGNUM *BN_get0_nist_prime_521(void); int (*BN_nist_mod_func(const BIGNUM *p))(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx); +int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv, + const unsigned char *message, size_t message_len, + BN_CTX *ctx); + /* library internal functions */ #define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\ @@ -868,6 +872,7 @@ void ERR_load_BN_strings(void); #define BN_R_NOT_INITIALIZED 107 #define BN_R_NO_INVERSE 108 #define BN_R_NO_SOLUTION 116 +#define BN_R_PRIVATE_KEY_TOO_LARGE 117 #define BN_R_P_IS_NOT_PRIME 112 #define BN_R_TOO_MANY_ITERATIONS 113 #define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c index cdc15e62f07b06b68992419afe630adddd0b572c..18a28ec2a658f935bf729ed1619272c7cd6ab406 100644 --- a/crypto/bn/bn_err.c +++ b/crypto/bn/bn_err.c @@ -1,6 +1,6 @@ /* crypto/bn/bn_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 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 @@ -132,6 +132,7 @@ static ERR_STRING_DATA BN_str_reasons[]= {ERR_REASON(BN_R_NOT_INITIALIZED) ,"not initialized"}, {ERR_REASON(BN_R_NO_INVERSE) ,"no inverse"}, {ERR_REASON(BN_R_NO_SOLUTION) ,"no solution"}, +{ERR_REASON(BN_R_PRIVATE_KEY_TOO_LARGE) ,"private key too large"}, {ERR_REASON(BN_R_P_IS_NOT_PRIME) ,"p is not prime"}, {ERR_REASON(BN_R_TOO_MANY_ITERATIONS) ,"too many iterations"}, {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),"too many temporary variables"}, diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c index 8d74895dedde6eebda62be5d9abb1164019e6409..d550f497d9f55da6b42aa4e1cee9d89eb4eba75d 100644 --- a/crypto/bn/bn_rand.c +++ b/crypto/bn/bn_rand.c @@ -116,6 +116,7 @@ #include "cryptlib.h" #include "bn_lcl.h" #include +#include static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) { @@ -313,3 +314,72 @@ int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { return bn_rand_range(1, r, range); } + +#ifndef OPENSSL_NO_SHA512 +/* BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike + * BN_rand_range, it also includes the contents of |priv| and |message| in the + * generation so that an RNG failure isn't fatal as long as |priv| remains + * secret. This is intended for use in DSA and ECDSA where an RNG weakness + * leads directly to private key exposure unless this function is used. */ +int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM* priv, + const unsigned char *message, size_t message_len, + BN_CTX *ctx) + { + SHA512_CTX sha; + /* We use 512 bits of random data per iteration to + * ensure that we have at least |range| bits of randomness. */ + unsigned char random_bytes[64]; + unsigned char digest[SHA512_DIGEST_LENGTH]; + unsigned done, todo; + /* We generate |range|+8 bytes of random output. */ + const unsigned num_k_bytes = BN_num_bytes(range) + 8; + unsigned char private_bytes[96]; + unsigned char *k_bytes; + int ret = 0; + + k_bytes = OPENSSL_malloc(num_k_bytes); + if (!k_bytes) + goto err; + + /* We copy |priv| into a local buffer to avoid exposing its length. */ + todo = sizeof(priv->d[0])*priv->top; + if (todo > sizeof(private_bytes)) + { + /* No reasonable DSA or ECDSA key should have a private key + * this large and we don't handle this case in order to avoid + * leaking the length of the private key. */ + BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE); + goto err; + } + memcpy(private_bytes, priv->d, todo); + memset(private_bytes + todo, 0, sizeof(private_bytes) - todo); + + for (done = 0; done < num_k_bytes;) { + if (RAND_bytes(random_bytes, sizeof(random_bytes)) != 1) + goto err; + SHA512_Init(&sha); + SHA512_Update(&sha, &done, sizeof(done)); + SHA512_Update(&sha, private_bytes, sizeof(private_bytes)); + SHA512_Update(&sha, message, message_len); + SHA512_Update(&sha, random_bytes, sizeof(random_bytes)); + SHA512_Final(digest, &sha); + + todo = num_k_bytes - done; + if (todo > SHA512_DIGEST_LENGTH) + todo = SHA512_DIGEST_LENGTH; + memcpy(k_bytes + done, digest, todo); + done += todo; + } + + if (!BN_bin2bn(k_bytes, num_k_bytes, out)) + goto err; + if (BN_mod(out, out, range, ctx) != 1) + goto err; + ret = 1; + +err: + if (k_bytes) + OPENSSL_free(k_bytes); + return ret; + } +#endif /* OPENSSL_NO_SHA512 */ diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 408ee11b7231cb1949810078d5853db961561281..28aa8a3073aec4d1e7451b60a358b3602a6567d2 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 a46fade4c6e338cc511ca6a4a9b17e0b4254d781..353d81aa7ccbbd2a4f104ac7d8eee02a207d93fb 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 485cff0b1934ed70be916983dbaef90c64c5c200..d1f80609b1e578f5d8935dcac6846cae54f5b7b0 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 599093a4a86d647b9271060583d22e57fcd7fd2b..b7e4caab2aff91ac2d37ced1621f080ef717ce78 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); } diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h index 0dcad23294e28823e42fbfe58aa9fc44bd814242..17fc91c94db0275da2624faa30b1fb687a53184f 100644 --- a/crypto/ec/ec.h +++ b/crypto/ec/ec.h @@ -823,6 +823,17 @@ void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, /* wrapper functions for the underlying EC_GROUP object */ void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); +/** Sets whether ECDSA operations with the given key will calculate their k + * value from SHA512(private_key + message + random) in order to protect + * against a weak PRNG. + * \param on Whether to calculate k from a hash or not + */ +void EC_KEY_set_nonce_from_hash(EC_KEY *key, int on); + +/** Returns the value of nonce_from_hash + */ +int EC_KEY_get_nonce_from_hash(const EC_KEY *key); + /** Creates a table of pre-computed multiples of the generator to * accelerate further EC_KEY operations. * \param key EC_KEY object diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index a91b9dc7f430f63593cbd158d8578938c7b6e646..7a15e5f159f82457e5655ea20db445028be5ce28 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -85,6 +85,7 @@ EC_KEY *EC_KEY_new(void) ret->pub_key = NULL; ret->priv_key= NULL; ret->enc_flag= 0; + ret->nonce_from_hash_flag = 0; ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; ret->references= 1; ret->method_data = NULL; @@ -198,6 +199,7 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) /* copy the rest */ dest->enc_flag = src->enc_flag; + dest->nonce_from_hash_flag = src->nonce_from_hash_flag; dest->conv_form = src->conv_form; dest->version = src->version; dest->flags = src->flags; @@ -589,6 +591,16 @@ void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) key->enc_flag = flags; } +int EC_KEY_get_nonce_from_hash(const EC_KEY *key) + { + return key->nonce_from_hash_flag; + } + +void EC_KEY_set_nonce_from_hash(EC_KEY *key, int on) + { + key->nonce_from_hash_flag = on != 0; + } + point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) { return key->conv_form; diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index da7967df38a36b670b8c74675b6e9b87b8280222..6f714c7575df1ac34bf33e00b4b6e2c701982f02 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -246,6 +246,7 @@ struct ec_key_st { BIGNUM *priv_key; unsigned int enc_flag; + char nonce_from_hash_flag; point_conversion_form_t conv_form; int references; diff --git a/crypto/ecdsa/ecdsa.h b/crypto/ecdsa/ecdsa.h index cd6d19ccdee5e285a039684163f09e9fba437d02..865c3302eee1acdb30a8cab77a468456ed53d4cc 100644 --- a/crypto/ecdsa/ecdsa.h +++ b/crypto/ecdsa/ecdsa.h @@ -264,6 +264,7 @@ void ERR_load_ECDSA_strings(void); #define ECDSA_R_ERR_EC_LIB 102 #define ECDSA_R_MISSING_PARAMETERS 103 #define ECDSA_R_NEED_NEW_SETUP_VALUES 106 +#define ECDSA_R_NONCE_CANNOT_BE_PRECOMPUTED 107 #define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 #define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 diff --git a/crypto/ecdsa/ecs_err.c b/crypto/ecdsa/ecs_err.c index 98e38d537f24c57714de613304a3cb954ba0d08b..17ccb4085ca3b6a27d0feef8b24e8571cae74d0b 100644 --- a/crypto/ecdsa/ecs_err.c +++ b/crypto/ecdsa/ecs_err.c @@ -1,6 +1,6 @@ /* crypto/ecdsa/ecs_err.c */ /* ==================================================================== - * Copyright (c) 1999-2006 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 @@ -84,6 +84,7 @@ static ERR_STRING_DATA ECDSA_str_reasons[]= {ERR_REASON(ECDSA_R_ERR_EC_LIB) ,"err ec lib"}, {ERR_REASON(ECDSA_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"}, +{ERR_REASON(ECDSA_R_NONCE_CANNOT_BE_PRECOMPUTED),"nonce cannot be precomputed"}, {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"}, {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"}, {0,NULL} diff --git a/crypto/ecdsa/ecs_locl.h b/crypto/ecdsa/ecs_locl.h index cb3be13cfc307025266aff78f47099ff0b5c7971..46f7ad910207a8c95c551a0977eecc9a4d914f78 100644 --- a/crypto/ecdsa/ecs_locl.h +++ b/crypto/ecdsa/ecs_locl.h @@ -70,8 +70,9 @@ struct ecdsa_method const char *name; ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey); - int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, - BIGNUM **r); + int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, + BIGNUM **kinv, BIGNUM **r, + const unsigned char *dgst, int dlen); int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); #if 0 diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c index 8336bceb673b6fcd96552a8fa7ed2a9e2e50d83a..113e60c4b9b1117be4a4391ba7689f7e7b36b652 100644 --- a/crypto/ecdsa/ecs_ossl.c +++ b/crypto/ecdsa/ecs_ossl.c @@ -62,11 +62,13 @@ #include #include #include +#include static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, const BIGNUM *, const BIGNUM *, EC_KEY *eckey); -static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp); +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp, + const unsigned char *dgst, int dlen); static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey); @@ -88,8 +90,9 @@ const ECDSA_METHOD *ECDSA_OpenSSL(void) return &openssl_ecdsa_meth; } -static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp) +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp, + const unsigned char *dgst, int dlen) { BN_CTX *ctx = NULL; BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; @@ -143,11 +146,26 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, { /* get random k */ do - if (!BN_rand_range(k, order)) +#ifndef OPENSSL_NO_SHA512 + if (EC_KEY_get_nonce_from_hash(eckey)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, - ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); - goto err; + if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey), + dgst, dlen, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); + goto err; + } + } + else +#endif + { + if (!BN_rand_range(k, order)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); + goto err; + } } while (BN_is_zero(k)); @@ -302,8 +320,7 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, { if (in_kinv == NULL || in_r == NULL) { - if (!ecdsa->meth->ecdsa_sign_setup(eckey, ctx, - &kinv, &ret->r)) + if (!ecdsa->meth->ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) { ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB); goto err; diff --git a/crypto/ecdsa/ecs_sign.c b/crypto/ecdsa/ecs_sign.c index 353d5af5146def603242fb1af0090c67fc714842..ea79a24b85da1fb8636bef8586b7138f3bda3bac 100644 --- a/crypto/ecdsa/ecs_sign.c +++ b/crypto/ecdsa/ecs_sign.c @@ -58,6 +58,7 @@ #include #endif #include +#include ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) { @@ -102,5 +103,12 @@ int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, ECDSA_DATA *ecdsa = ecdsa_check(eckey); if (ecdsa == NULL) return 0; - return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); + if (EC_KEY_get_nonce_from_hash(eckey)) + { + /* You cannot precompute the ECDSA nonce if it is required to + * depend on the message. */ + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_NONCE_CANNOT_BE_PRECOMPUTED); + return 0; + } + return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0); }