Redirect DSA operations to FIPS module in FIPS mode.
[oweals/openssl.git] / crypto / dsa / dsa_gen.c
index 6d428447efe7b2997d000d7a97f5e4d1023c0e3c..cc73a23724fe15f796597d55aef8b9b7d1ed7da7 100644 (file)
 #include <openssl/sha.h>
 #include "dsa_locl.h"
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 int DSA_generate_parameters_ex(DSA *ret, int bits,
-               unsigned char *seed_in, int seed_len,
+               const unsigned char *seed_in, int seed_len,
                int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
        {
+       if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)
+                       && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD);
+               return 0;
+               }
+
        if(ret->meth->dsa_paramgen)
                return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
                                counter_ret, h_ret, cb);
+#ifdef OPENSSL_FIPS
+       else if (FIPS_mode())
+               {
+               return FIPS_dsa_generate_parameters_ex(ret, bits, 
+                                                       seed_in, seed_len,
+                                                       counter_ret, h_ret, cb);
+               }
+#endif
        else
                {
                const EVP_MD *evpmd;
@@ -105,12 +124,13 @@ int DSA_generate_parameters_ex(DSA *ret, int bits,
                        }
 
                return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
-                               seed_in, seed_len, counter_ret, h_ret, cb);
+                       seed_in, seed_len, NULL, counter_ret, h_ret, cb);
                }
        }
 
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
-       const EVP_MD *evpmd, unsigned char *seed_in, size_t seed_len,
+       const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+       unsigned char *seed_out,
        int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
        {
        int ok=0;
@@ -120,7 +140,7 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
        BIGNUM *r0,*W,*X,*c,*test;
        BIGNUM *g=NULL,*q=NULL,*p=NULL;
        BN_MONT_CTX *mont=NULL;
-       int i, k,n=0,b,m=0, qsize = qbits >> 3;
+       int i, k, n=0, m=0, qsize = qbits >> 3;
        int counter=0;
        int r=0;
        BN_CTX *ctx=NULL;
@@ -140,9 +160,12 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
 
        bits = (bits+63)/64*64;
 
-       if (seed_len < qsize)
+       /* NB: seed_len == 0 is special case: copy generated seed to
+        * seed_in if it is not NULL.
+        */
+       if (seed_len && (seed_len < (size_t)qsize))
                seed_in = NULL;         /* seed buffer too small -- ignore */
-       if (seed_len > qsize) 
+       if (seed_len > (size_t)qsize) 
                seed_len = qsize;       /* App. 2.2 of FIPS PUB 186 allows larger SEED,
                                         * but our internal buffers are restricted to 160 bits*/
        if (seed_in != NULL)
@@ -198,8 +221,10 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                                }
 
                        /* step 2 */
-                       EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL);
-                       EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL);
+                       if (!EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL))
+                               goto err;
+                       if (!EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL))
+                               goto err;
                        for (i = 0; i < qsize; i++)
                                md[i]^=buf2[i];
 
@@ -229,7 +254,6 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                /* "offset = 2" */
 
                n=(bits-1)/160;
-               b=(bits-1)-n*160;
 
                for (;;)
                        {
@@ -249,7 +273,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                                                break;
                                        }
 
-                               EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL);
+                               if (!EVP_Digest(buf, qsize, md ,NULL, evpmd,
+                                                                       NULL))
+                                       goto err;
 
                                /* step 8 */
                                if (!BN_bin2bn(md, qsize, r0))
@@ -328,9 +354,10 @@ err:
                        ok=0;
                        goto err;
                        }
-               if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed, qsize);
                if (counter_ret != NULL) *counter_ret=counter;
                if (h_ret != NULL) *h_ret=h;
+               if (seed_out)
+                       memcpy(seed_out, seed, qsize);
                }
        if(ctx)
                {