remove FIPS module code from crypto/dsa
[openssl.git] / crypto / dsa / dsa_ossl.c
index 33ac3e130e3dfd1677c847dfcf7c8f6e2b553c9f..bec13541b91f34c5aa18c2e829d7a5ec374493ea 100644 (file)
@@ -58,6 +58,8 @@
 
 /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
 
+#define OPENSSL_FIPSAPI
+
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/bn.h>
 #include <openssl/dsa.h>
 #include <openssl/rand.h>
 #include <openssl/asn1.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
 
 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_no_digest(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);
@@ -79,7 +81,7 @@ static int dsa_finish(DSA *dsa);
 static DSA_METHOD openssl_dsa_meth = {
 "OpenSSL DSA method",
 dsa_do_sign,
-dsa_sign_setup,
+dsa_sign_setup_no_digest,
 dsa_do_verify,
 NULL, /* dsa_mod_exp, */
 NULL, /* dsa_bn_mod_exp, */
@@ -141,20 +143,6 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        DSA_SIG *ret=NULL;
        int noredo = 0;
 
-#ifdef OPENSSL_FIPS
-       if(FIPS_selftest_failed())
-           {
-           FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED);
-           return NULL;
-           }
-
-       if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
-               {
-               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL);
-               return NULL;
-               }
-#endif
-
        BN_init(&m);
        BN_init(&xr);
 
@@ -166,21 +154,13 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
 
        s=BN_new();
        if (s == NULL) goto err;
-
-       /* reject a excessive digest length (currently at most
-        * dsa-with-SHA256 is supported) */
-       if (dlen > SHA256_DIGEST_LENGTH)
-               {
-               reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
-               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_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen))
+                       goto err;
                }
        else
                {
@@ -239,7 +219,14 @@ err:
        return(ret);
        }
 
-static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in,
+                         BIGNUM **kinvp, BIGNUM **rp) {
+       return dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0);
+}
+
+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;
@@ -265,8 +252,22 @@ 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 (dgst != NULL)
+                       {
+                       /* 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);
@@ -351,34 +352,11 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
                return -1;
                }
 
-#ifdef OPENSSL_FIPS
-       if(FIPS_selftest_failed())
-           {
-           FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED);
-           return -1;
-           }
-
-       if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
-               {
-               DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL);
-               return -1;
-               }
-#endif
-
        if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
                {
                DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
                return -1;
                }
-
-       /* reject a excessive digest length (currently at most
-        * dsa-with-SHA256 is supported) */
-       if (dgst_len > SHA256_DIGEST_LENGTH)
-               {
-               DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
-               return -1;
-               }
-
        BN_init(&u1);
        BN_init(&u2);
        BN_init(&t1);
@@ -436,9 +414,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
        ret=(BN_ucmp(&u1, sig->r) == 0);
 
        err:
-       /* XXX: surely this is wrong - if ret is 0, it just didn't verify;
-          there is no error in BN. Test should be ret == -1 (Ben) */
-       if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+       if (ret < 0) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
        if (ctx != NULL) BN_CTX_free(ctx);
        BN_free(&u1);
        BN_free(&u2);