summaryrefslogtreecommitdiff
path: root/main/openssl/crypto/dsa/dsa_ossl.c
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2014-04-23 09:56:37 +0200
committerArne Schwabe <arne@rfc2549.org>2014-04-23 09:56:37 +0200
commite436c963f0976b885a7db04681344779e26dd3b5 (patch)
tree240663106f32e02e1c34080656f4ef21a2e1776e /main/openssl/crypto/dsa/dsa_ossl.c
parent6a99715a9b072fa249e79c98cd9f03991f0f1219 (diff)
Update OpenSSL to 1.0.1g and statically link OpenVPN with it
Diffstat (limited to 'main/openssl/crypto/dsa/dsa_ossl.c')
-rw-r--r--main/openssl/crypto/dsa/dsa_ossl.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/main/openssl/crypto/dsa/dsa_ossl.c b/main/openssl/crypto/dsa/dsa_ossl.c
index a3ddd7d2..177fc545 100644
--- a/main/openssl/crypto/dsa/dsa_ossl.c
+++ b/main/openssl/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);
@@ -136,6 +138,7 @@ 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;
BN_init(&m);
BN_init(&xr);
@@ -150,10 +153,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
if (s == NULL) 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->meth->dsa_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen))
+ goto err;
}
else
{
@@ -161,6 +165,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;
}
@@ -181,6 +186,18 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
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;
@@ -199,7 +216,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;
@@ -225,8 +244,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);