summaryrefslogtreecommitdiffstats
path: root/crypto/dsa
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2011-01-25 16:01:29 +0000
committerDr. Stephen Henson <steve@openssl.org>2011-01-25 16:01:29 +0000
commit245a7eee177ccd7fd7986f86b67a4d59f5c4d6ad (patch)
tree3acdbc11584c04330c8fd8ae3fac6146660f3666 /crypto/dsa
parent6e0375d504c4bc8daec5a938c9d3232db3a72500 (diff)
recalculate DSA signature if r or s is zero (FIPS 186-3 requirement)
Diffstat (limited to 'crypto/dsa')
-rw-r--r--crypto/dsa/dsa.h1
-rw-r--r--crypto/dsa/dsa_err.c1
-rw-r--r--crypto/dsa/dsa_ossl.c16
3 files changed, 17 insertions, 1 deletions
diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h
index bbe8cb579c..3d401830a9 100644
--- a/crypto/dsa/dsa.h
+++ b/crypto/dsa/dsa.h
@@ -299,6 +299,7 @@ void ERR_load_DSA_strings(void);
#define DSA_R_INVALID_DIGEST_TYPE 106
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_MODULUS_TOO_LARGE 103
+#define DSA_R_NEED_NEW_SETUP_VALUES 110
#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 a1e9993c95..fda04af24b 100644
--- a/crypto/dsa/dsa_err.c
+++ b/crypto/dsa/dsa_err.c
@@ -106,6 +106,7 @@ static ERR_STRING_DATA DSA_str_reasons[]=
{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
{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_NO_PARAMETERS_SET) ,"no parameters set"},
{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
{0,NULL}
diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c
index 1fb665ec57..1b416901b4 100644
--- a/crypto/dsa/dsa_ossl.c
+++ b/crypto/dsa/dsa_ossl.c
@@ -136,6 +136,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);
@@ -159,7 +160,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
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;
@@ -170,6 +171,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;
}
@@ -190,6 +192,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;