From 190c615d4398cc6c8b61eb7881d7409314529a75 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Mon, 15 Jul 2013 12:42:15 +0100 Subject: [PATCH] Make `safe' (EC)DSA nonces the default. This change updates 8a99cb29 to make the generation of (EC)DSA nonces using the message digest the default. It also reverts the changes to (EC)DSA_METHOD structure. In addition to making it the default, removing the flag from EC_KEY means that FIPS modules will no longer have an ABI mismatch. --- crypto/dsa/dsa.h | 14 ++------------ crypto/dsa/dsa_err.c | 1 - crypto/dsa/dsa_ossl.c | 26 ++++++++++++++++---------- crypto/dsa/dsa_sign.c | 9 +-------- crypto/ec/ec.h | 11 ----------- crypto/ec/ec_key.c | 12 ------------ crypto/ec/ec_lcl.h | 1 - crypto/ecdsa/ecdsa.h | 1 - crypto/ecdsa/ecs_err.c | 1 - crypto/ecdsa/ecs_locl.h | 5 ++--- crypto/ecdsa/ecs_ossl.c | 24 ++++++++++++++++-------- crypto/ecdsa/ecs_sign.c | 10 +--------- 12 files changed, 38 insertions(+), 77 deletions(-) diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 28aa8a3073..6010a954f0 100644 --- a/crypto/dsa/dsa.h +++ b/crypto/dsa/dsa.h @@ -104,14 +104,6 @@ * 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 @@ -147,9 +139,8 @@ 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, - const unsigned char *dgst, int dlen); + int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); 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, @@ -353,7 +344,6 @@ 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 353d81aa7c..084392e7cf 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -112,7 +112,6 @@ 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 d1f80609b1..fb82c16d01 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -72,9 +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, - const unsigned char *dgst, int dlen); +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); +static int dsa_sign_setup_with_digest(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); @@ -178,7 +179,7 @@ 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,dgst,dlen)) + if (!dsa_sign_setup_with_digest(dsa,ctx,&kinv,&r,dgst,dlen)) goto err; } else @@ -239,8 +240,13 @@ err: } static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, - BIGNUM **kinvp, BIGNUM **rp, - const unsigned char *dgst, int dlen) + BIGNUM **kinvp, BIGNUM **rp) { + return dsa_sign_setup_with_digest(dsa, ctx_in, kinvp, rp, NULL, 0); +} + +static int dsa_sign_setup_with_digest(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; @@ -268,11 +274,11 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, do { #ifndef OPENSSL_NO_SHA512 - if (dsa->flags & DSA_FLAG_NONCE_FROM_HASH) + if (dgst != NULL) { - /* 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. */ + /* 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; diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index b7e4caab2a..599093a4a8 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -72,12 +72,5 @@ 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) { - 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); + return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); } diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h index 17fc91c94d..0dcad23294 100644 --- a/crypto/ec/ec.h +++ b/crypto/ec/ec.h @@ -823,17 +823,6 @@ 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 7a15e5f159..a91b9dc7f4 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -85,7 +85,6 @@ 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; @@ -199,7 +198,6 @@ 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; @@ -591,16 +589,6 @@ 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 6f714c7575..da7967df38 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -246,7 +246,6 @@ 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 865c3302ee..cd6d19ccde 100644 --- a/crypto/ecdsa/ecdsa.h +++ b/crypto/ecdsa/ecdsa.h @@ -264,7 +264,6 @@ 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 17ccb4085c..d549ee5323 100644 --- a/crypto/ecdsa/ecs_err.c +++ b/crypto/ecdsa/ecs_err.c @@ -84,7 +84,6 @@ 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 46f7ad9102..ad466e2b61 100644 --- a/crypto/ecdsa/ecs_locl.h +++ b/crypto/ecdsa/ecs_locl.h @@ -70,9 +70,8 @@ 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, - const unsigned char *dgst, int dlen); + int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **r); 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 113e60c4b9..9f7aecf5ee 100644 --- a/crypto/ecdsa/ecs_ossl.c +++ b/crypto/ecdsa/ecs_ossl.c @@ -66,9 +66,11 @@ 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, - const unsigned char *dgst, int dlen); +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int ecdsa_sign_setup_with_digest(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); @@ -90,9 +92,14 @@ 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, - const unsigned char *dgst, int dlen) +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) { + return ecdsa_sign_setup_with_digest(eckey, ctx_in, kinvp, rp, NULL, 0); +} + +static int ecdsa_sign_setup_with_digest(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; @@ -147,7 +154,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, /* get random k */ do #ifndef OPENSSL_NO_SHA512 - if (EC_KEY_get_nonce_from_hash(eckey)) + if (dgst != NULL) { if (!BN_generate_dsa_nonce(k, order, EC_KEY_get0_private_key(eckey), dgst, dlen, ctx)) @@ -320,7 +327,8 @@ 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, dgst, dgst_len)) + if (!ecdsa_sign_setup_with_digest( + 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 ea79a24b85..042b1565ec 100644 --- a/crypto/ecdsa/ecs_sign.c +++ b/crypto/ecdsa/ecs_sign.c @@ -58,7 +58,6 @@ #include #endif #include -#include ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) { @@ -103,12 +102,5 @@ int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, ECDSA_DATA *ecdsa = ecdsa_check(eckey); if (ecdsa == NULL) return 0; - 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); + return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); } -- 2.25.1