Redirect DSA operations to FIPS module in FIPS mode.
authorDr. Stephen Henson <steve@openssl.org>
Thu, 9 Jun 2011 13:54:09 +0000 (13:54 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 9 Jun 2011 13:54:09 +0000 (13:54 +0000)
CHANGES
crypto/dsa/dsa.h
crypto/dsa/dsa_err.c
crypto/dsa/dsa_gen.c
crypto/dsa/dsa_lib.c
crypto/dsa/dsa_sign.c
crypto/dsa/dsa_vrf.c

diff --git a/CHANGES b/CHANGES
index 386ca46..647836b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,9 @@
 
  Changes between 1.0.0d and 1.0.1  [xx XXX xxxx]
 
+  *) Redirect DSA and DH operations to FIPS module in FIPS mode.
+     [Steve Henson]
+
   *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use
      FIPS EC methods unconditionally for now.
      [Steve Henson]
index 3d362d1..6a21b2c 100644 (file)
                                               * be used for all exponents.
                                               */
 
+/* If this flag is set the DSA method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its reposibility
+ * to ensure the result is compliant.
+ */
+
+#define DSA_FLAG_FIPS_METHOD                   0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define DSA_FLAG_NON_FIPS_ALLOW                        0x0400
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -272,6 +287,7 @@ void ERR_load_DSA_strings(void);
 #define DSA_F_DSAPARAMS_PRINT_FP                        101
 #define DSA_F_DSA_DO_SIGN                               112
 #define DSA_F_DSA_DO_VERIFY                             113
+#define DSA_F_DSA_GENERATE_PARAMETERS_EX                123
 #define DSA_F_DSA_NEW_METHOD                            103
 #define DSA_F_DSA_PARAM_DECODE                          119
 #define DSA_F_DSA_PRINT_FP                              105
@@ -299,6 +315,7 @@ void ERR_load_DSA_strings(void);
 #define DSA_R_MISSING_PARAMETERS                        101
 #define DSA_R_MODULUS_TOO_LARGE                                 103
 #define DSA_R_NEED_NEW_SETUP_VALUES                     110
+#define DSA_R_NON_FIPS_DSA_METHOD                       111
 #define DSA_R_NO_PARAMETERS_SET                                 107
 #define DSA_R_PARAMETER_ENCODING_ERROR                  105
 
index 2981eab..bada41f 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/dsa/dsa_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -76,6 +76,7 @@ static ERR_STRING_DATA DSA_str_functs[]=
 {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP),   "DSAparams_print_fp"},
 {ERR_FUNC(DSA_F_DSA_DO_SIGN),  "DSA_do_sign"},
 {ERR_FUNC(DSA_F_DSA_DO_VERIFY),        "DSA_do_verify"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX),   "DSA_generate_parameters_ex"},
 {ERR_FUNC(DSA_F_DSA_NEW_METHOD),       "DSA_new_method"},
 {ERR_FUNC(DSA_F_DSA_PARAM_DECODE),     "DSA_PARAM_DECODE"},
 {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
@@ -106,6 +107,7 @@ static ERR_STRING_DATA DSA_str_reasons[]=
 {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_NON_FIPS_DSA_METHOD)   ,"non fips dsa method"},
 {ERR_REASON(DSA_R_NO_PARAMETERS_SET)     ,"no parameters set"},
 {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
 {0,NULL}
index e6a5452..cc73a23 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,
                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;
index e9b7590..f796090 100644 (file)
 #include <openssl/dh.h>
 #endif
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;
 
 static const DSA_METHOD *default_DSA_method = NULL;
@@ -82,7 +86,14 @@ void DSA_set_default_method(const DSA_METHOD *meth)
 const DSA_METHOD *DSA_get_default_method(void)
        {
        if(!default_DSA_method)
-               default_DSA_method = DSA_OpenSSL();
+               {
+#ifdef OPENSSL_FIPS
+               if (FIPS_mode())
+                       default_DSA_method = FIPS_dsa_openssl();
+               else
+#endif
+                       default_DSA_method = DSA_OpenSSL();
+               }
        return default_DSA_method;
        }
 
@@ -163,7 +174,7 @@ DSA *DSA_new_method(ENGINE *engine)
        ret->method_mont_p=NULL;
 
        ret->references=1;
-       ret->flags=ret->meth->flags;
+       ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
        CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
        if ((ret->meth->init != NULL) && !ret->meth->init(ret))
                {
index e02365a..c3cc364 100644 (file)
 
 DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+                       && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD);
+               return NULL;
+               }
+#endif
        return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
        }
 
 int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+                       && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD);
+               return 0;
+               }
+#endif
        return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
        }
 
index 286ed28..674cb5f 100644 (file)
 int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
                  DSA *dsa)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD)
+                       && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD);
+               return -1;
+               }
+#endif
        return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
        }