mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-28 12:35:17 +00:00
d83a3d71bc
Merge in RedPhone // FREEBIE
503 lines
18 KiB
Diff
503 lines
18 KiB
Diff
From 9be2984bfbff9a83e7b38f47ac87c677e9a9a0b8 Mon Sep 17 00:00:00 2001
|
|
From: Adam Langley <agl@chromium.org>
|
|
Date: Thu, 24 Jan 2013 16:27:28 -0500
|
|
Subject: dsa_nonce
|
|
|
|
Adds the option to calculate (EC)DSA nonces by hashing the message and
|
|
private key along with entropy.
|
|
---
|
|
crypto/bn/bn.h | 6 +++++
|
|
crypto/bn/bn_err.c | 2 ++
|
|
crypto/bn/bn_rand.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
crypto/dsa/dsa.h | 10 +++++--
|
|
crypto/dsa/dsa_err.c | 1 +
|
|
crypto/dsa/dsa_ossl.c | 28 ++++++++++++++++----
|
|
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 | 38 ++++++++++++++++++++-------
|
|
crypto/ecdsa/ecs_sign.c | 10 ++++++-
|
|
15 files changed, 185 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h
|
|
index f34248e..9281ce5 100644
|
|
--- a/crypto/bn/bn.h
|
|
+++ b/crypto/bn/bn.h
|
|
@@ -692,6 +692,10 @@ const BIGNUM *BN_get0_nist_prime_256(void);
|
|
const BIGNUM *BN_get0_nist_prime_384(void);
|
|
const BIGNUM *BN_get0_nist_prime_521(void);
|
|
|
|
+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)?\
|
|
@@ -842,6 +846,7 @@ void ERR_load_BN_strings(void);
|
|
#define BN_F_BN_EXP 123
|
|
#define BN_F_BN_EXPAND2 108
|
|
#define BN_F_BN_EXPAND_INTERNAL 120
|
|
+#define BN_F_BN_GENERATE_DSA_NONCE 140
|
|
#define BN_F_BN_GF2M_MOD 131
|
|
#define BN_F_BN_GF2M_MOD_EXP 132
|
|
#define BN_F_BN_GF2M_MOD_MUL 133
|
|
@@ -881,6 +886,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 cfe2eb9..f722b52 100644
|
|
--- a/crypto/bn/bn_err.c
|
|
+++ b/crypto/bn/bn_err.c
|
|
@@ -87,6 +87,7 @@ static ERR_STRING_DATA BN_str_functs[]=
|
|
{ERR_FUNC(BN_F_BN_EXP), "BN_exp"},
|
|
{ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"},
|
|
{ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"},
|
|
+{ERR_FUNC(BN_F_BN_GENERATE_DSA_NONCE), "BN_generate_dsa_nonce"},
|
|
{ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"},
|
|
{ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"},
|
|
{ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"},
|
|
@@ -129,6 +130,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 b376c28..55676f0 100644
|
|
--- a/crypto/bn/bn_rand.c
|
|
+++ b/crypto/bn/bn_rand.c
|
|
@@ -114,6 +114,7 @@
|
|
#include "cryptlib.h"
|
|
#include "bn_lcl.h"
|
|
#include <openssl/rand.h>
|
|
+#include <openssl/sha.h>
|
|
|
|
static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
|
|
{
|
|
@@ -303,3 +304,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 b448d2a..71ef572 100644
|
|
--- a/crypto/dsa/dsa.h
|
|
+++ b/crypto/dsa/dsa.h
|
|
@@ -96,6 +96,10 @@
|
|
* 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
|
|
@@ -131,8 +135,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,
|
|
@@ -325,6 +330,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 112
|
|
#define DSA_R_NON_FIPS_DSA_METHOD 111
|
|
#define DSA_R_NO_PARAMETERS_SET 107
|
|
#define DSA_R_PARAMETER_ENCODING_ERROR 105
|
|
diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c
|
|
index 00545b7..e6171cc 100644
|
|
--- a/crypto/dsa/dsa_err.c
|
|
+++ b/crypto/dsa/dsa_err.c
|
|
@@ -109,6 +109,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_NON_FIPS_DSA_METHOD) ,"non fips dsa method"},
|
|
{ERR_REASON(DSA_R_NO_PARAMETERS_SET) ,"no parameters set"},
|
|
{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
|
|
diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c
|
|
index a865a8c..15f8da2 100644
|
|
--- a/crypto/dsa/dsa_ossl.c
|
|
+++ b/crypto/dsa/dsa_ossl.c
|
|
@@ -67,7 +67,9 @@
|
|
#include <openssl/asn1.h>
|
|
|
|
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);
|
|
@@ -167,7 +169,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_sign_setup(dsa,ctx,&kinv,&r)) goto err;
|
|
+ if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen))
|
|
+ goto err;
|
|
}
|
|
else
|
|
{
|
|
@@ -226,7 +229,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;
|
|
@@ -252,8 +257,21 @@ 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 c3cc364..8ace300 100644
|
|
--- a/crypto/dsa/dsa_sign.c
|
|
+++ b/crypto/dsa/dsa_sign.c
|
|
@@ -86,7 +86,14 @@ int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
|
|
return 0;
|
|
}
|
|
#endif
|
|
- return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
|
|
+ if (dsa->flags & DSA_FLAG_NONCE_FROM_HASH)
|
|
+ {
|
|
+ /* You 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);
|
|
}
|
|
|
|
DSA_SIG *DSA_SIG_new(void)
|
|
diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h
|
|
index dfe8710..d008a0d 100644
|
|
--- a/crypto/ec/ec.h
|
|
+++ b/crypto/ec/ec.h
|
|
@@ -819,6 +819,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 7fa2475..73dd7b9 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;
|
|
@@ -505,6 +507,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 da7967d..6f714c7 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 7fb5254..dc6a36b 100644
|
|
--- a/crypto/ecdsa/ecdsa.h
|
|
+++ b/crypto/ecdsa/ecdsa.h
|
|
@@ -250,6 +250,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 108
|
|
#define ECDSA_R_NON_FIPS_METHOD 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 81542e6..7406c6d 100644
|
|
--- a/crypto/ecdsa/ecs_err.c
|
|
+++ b/crypto/ecdsa/ecs_err.c
|
|
@@ -85,6 +85,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_NON_FIPS_METHOD) ,"non fips method"},
|
|
{ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"},
|
|
{ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"},
|
|
diff --git a/crypto/ecdsa/ecs_locl.h b/crypto/ecdsa/ecs_locl.h
|
|
index cb3be13..46f7ad9 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 7725935..325aca8 100644
|
|
--- a/crypto/ecdsa/ecs_ossl.c
|
|
+++ b/crypto/ecdsa/ecs_ossl.c
|
|
@@ -60,11 +60,13 @@
|
|
#include <openssl/err.h>
|
|
#include <openssl/obj_mac.h>
|
|
#include <openssl/bn.h>
|
|
+#include <openssl/rand.h>
|
|
|
|
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);
|
|
|
|
@@ -86,8 +88,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;
|
|
@@ -136,11 +139,28 @@ 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));
|
|
|
|
@@ -282,7 +302,7 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
|
|
{
|
|
if (in_kinv == NULL || in_r == NULL)
|
|
{
|
|
- if (!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 353d5af..ea79a24 100644
|
|
--- a/crypto/ecdsa/ecs_sign.c
|
|
+++ b/crypto/ecdsa/ecs_sign.c
|
|
@@ -58,6 +58,7 @@
|
|
#include <openssl/engine.h>
|
|
#endif
|
|
#include <openssl/rand.h>
|
|
+#include <openssl/err.h>
|
|
|
|
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);
|
|
}
|
|
--
|
|
1.8.5.1
|
|
|