summaryrefslogtreecommitdiff
path: root/app/openssl/crypto/dsa/dsa_ossl.c
diff options
context:
space:
mode:
authorParménides GV <parmegv@sdf.org>2014-06-13 12:13:04 +0200
committerParménides GV <parmegv@sdf.org>2014-06-13 12:13:04 +0200
commit3a71bc9e4aa4296f460e2e3c55de74c9852477ad (patch)
treef816597a7c4322137f0657e7aa2bf392404d1870 /app/openssl/crypto/dsa/dsa_ossl.c
parentcfe67bfd8260253ce9288225b9e26f666d27133f (diff)
parent36247e71df88fa13c6c5a887de3b11d9a883615f (diff)
Merge branch 'feature/establish-an-upstream-relationship-with-ics-openvpn-codebase-#5381' into develop
Diffstat (limited to 'app/openssl/crypto/dsa/dsa_ossl.c')
-rw-r--r--app/openssl/crypto/dsa/dsa_ossl.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/app/openssl/crypto/dsa/dsa_ossl.c b/app/openssl/crypto/dsa/dsa_ossl.c
index a3ddd7d2..177fc545 100644
--- a/app/openssl/crypto/dsa/dsa_ossl.c
+++ b/app/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);