| Index: openssl/crypto/dsa/dsa_ossl.c
|
| ===================================================================
|
| --- openssl/crypto/dsa/dsa_ossl.c (revision 105093)
|
| +++ openssl/crypto/dsa/dsa_ossl.c (working copy)
|
| @@ -61,16 +61,15 @@
|
| #include <stdio.h>
|
| #include "cryptlib.h"
|
| #include <openssl/bn.h>
|
| +#include <openssl/sha.h>
|
| #include <openssl/dsa.h>
|
| #include <openssl/rand.h>
|
| #include <openssl/asn1.h>
|
|
|
| -#ifndef OPENSSL_FIPS
|
| -
|
| 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_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
|
| - DSA *dsa);
|
| + DSA *dsa);
|
| static int dsa_init(DSA *dsa);
|
| static int dsa_finish(DSA *dsa);
|
|
|
| @@ -135,7 +134,7 @@
|
| BIGNUM m;
|
| BIGNUM xr;
|
| BN_CTX *ctx=NULL;
|
| - int i,reason=ERR_R_BN_LIB;
|
| + int reason=ERR_R_BN_LIB;
|
| DSA_SIG *ret=NULL;
|
|
|
| BN_init(&m);
|
| @@ -149,14 +148,6 @@
|
|
|
| s=BN_new();
|
| if (s == NULL) goto err;
|
| -
|
| - i=BN_num_bytes(dsa->q); /* should be 20 */
|
| - if ((dlen > i) || (dlen > 50))
|
| - {
|
| - reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
|
| - goto err;
|
| - }
|
| -
|
| ctx=BN_CTX_new();
|
| if (ctx == NULL) goto err;
|
|
|
| @@ -172,13 +163,20 @@
|
| dsa->r=NULL;
|
| }
|
|
|
| - if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
|
| +
|
| + if (dlen > BN_num_bytes(dsa->q))
|
| + /* if the digest length is greater than the size of q use the
|
| + * BN_num_bits(dsa->q) leftmost bits of the digest, see
|
| + * fips 186-3, 4.2 */
|
| + dlen = BN_num_bytes(dsa->q);
|
| + if (BN_bin2bn(dgst,dlen,&m) == NULL)
|
| + goto err;
|
|
|
| /* Compute s = inv(k) (m + xr) mod q */
|
| if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
|
| if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
|
| if (BN_cmp(s,dsa->q) > 0)
|
| - BN_sub(s,s,dsa->q);
|
| + if (!BN_sub(s,s,dsa->q)) goto err;
|
| if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
|
|
|
| ret=DSA_SIG_new();
|
| @@ -283,30 +281,31 @@
|
| if (!ret)
|
| {
|
| DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
|
| - if (kinv != NULL) BN_clear_free(kinv);
|
| - if (r != NULL) BN_clear_free(r);
|
| + if (r != NULL)
|
| + BN_clear_free(r);
|
| }
|
| if (ctx_in == NULL) BN_CTX_free(ctx);
|
| - if (kinv != NULL) BN_clear_free(kinv);
|
| BN_clear_free(&k);
|
| BN_clear_free(&kq);
|
| return(ret);
|
| }
|
|
|
| static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
|
| - DSA *dsa)
|
| + DSA *dsa)
|
| {
|
| BN_CTX *ctx;
|
| BIGNUM u1,u2,t1;
|
| BN_MONT_CTX *mont=NULL;
|
| - int ret = -1;
|
| + int ret = -1, i;
|
| if (!dsa->p || !dsa->q || !dsa->g)
|
| {
|
| DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
|
| return -1;
|
| }
|
|
|
| - if (BN_num_bits(dsa->q) != 160)
|
| + i = BN_num_bits(dsa->q);
|
| + /* fips 186-3 allows only different sizes for q */
|
| + if (i != 160 && i != 224 && i != 256)
|
| {
|
| DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
|
| return -1;
|
| @@ -317,7 +316,6 @@
|
| DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
|
| return -1;
|
| }
|
| -
|
| BN_init(&u1);
|
| BN_init(&u2);
|
| BN_init(&t1);
|
| @@ -342,6 +340,11 @@
|
| if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
|
|
|
| /* save M in u1 */
|
| + if (dgst_len > (i >> 3))
|
| + /* if the digest length is greater than the size of q use the
|
| + * BN_num_bits(dsa->q) leftmost bits of the digest, see
|
| + * fips 186-3, 4.2 */
|
| + dgst_len = (i >> 3);
|
| if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
|
|
|
| /* u1 = M * w mod q */
|
| @@ -393,4 +396,3 @@
|
| return(1);
|
| }
|
|
|
| -#endif
|
|
|