Redirection of low level APIs to FIPS module.
authorDr. Stephen Henson <steve@openssl.org>
Thu, 2 Jun 2011 18:22:42 +0000 (18:22 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 2 Jun 2011 18:22:42 +0000 (18:22 +0000)
Digest sign, verify operations are not redirected at this stage.

CHANGES
crypto/rsa/rsa.h
crypto/rsa/rsa_crpt.c
crypto/rsa/rsa_err.c
crypto/rsa/rsa_lib.c
crypto/rsa/rsa_sign.c

diff --git a/CHANGES b/CHANGES
index 2750153..466d952 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,10 @@
 
  Changes between 1.0.0d and 1.0.1  [xx XXX xxxx]
 
+  *) Redirect low level RSA operations to FIPS module including blocking of
+     non FIPS RSA methods.
+     [Steve Henson]
+
   *) Add similar low level API blocking to ciphers.
      [Steve Henson]
 
index d3906e1..68ae2e7 100644 (file)
@@ -419,6 +419,25 @@ void *RSA_get_ex_data(const RSA *r, int idx);
 RSA *RSAPublicKey_dup(RSA *rsa);
 RSA *RSAPrivateKey_dup(RSA *rsa);
 
+/* If this flag is set the RSA 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 responsibility
+ * to ensure the result is compliant.
+ */
+
+#define RSA_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 RSA_FLAG_NON_FIPS_ALLOW                        0x0400
+/* Application has decided PRNG is good enough to generate a key: don't
+ * check.
+ */
+#define RSA_FLAG_CHECKED                       0x0800
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -468,8 +487,12 @@ void ERR_load_RSA_strings(void);
 #define RSA_F_RSA_PADDING_CHECK_X931                    128
 #define RSA_F_RSA_PRINT                                         115
 #define RSA_F_RSA_PRINT_FP                              116
+#define RSA_F_RSA_PRIVATE_DECRYPT                       150
+#define RSA_F_RSA_PRIVATE_ENCRYPT                       151
 #define RSA_F_RSA_PRIV_DECODE                           137
 #define RSA_F_RSA_PRIV_ENCODE                           138
+#define RSA_F_RSA_PUBLIC_DECRYPT                        152
+#define RSA_F_RSA_PUBLIC_ENCRYPT                        153
 #define RSA_F_RSA_PUB_DECODE                            139
 #define RSA_F_RSA_SETUP_BLINDING                        136
 #define RSA_F_RSA_SIGN                                  117
@@ -513,6 +536,7 @@ void ERR_load_RSA_strings(void);
 #define RSA_R_KEY_SIZE_TOO_SMALL                        120
 #define RSA_R_LAST_OCTET_INVALID                        134
 #define RSA_R_MODULUS_TOO_LARGE                                 105
+#define RSA_R_NON_FIPS_RSA_METHOD                       150
 #define RSA_R_NO_PUBLIC_EXPONENT                        140
 #define RSA_R_NULL_BEFORE_BLOCK_MISSING                         113
 #define RSA_R_N_DOES_NOT_EQUAL_P_Q                      127
index 7750366..d3e4478 100644 (file)
@@ -75,24 +75,56 @@ int RSA_size(const RSA *r)
 int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
             RSA *rsa, int padding)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+                       && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+               return -1;
+               }
+#endif
        return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
        }
 
 int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
             RSA *rsa, int padding)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+                       && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+               return -1;
+               }
+#endif
        return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
        }
 
 int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
             RSA *rsa, int padding)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+                       && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+               return -1;
+               }
+#endif
        return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
        }
 
 int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
             RSA *rsa, int padding)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+                       && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
+               return -1;
+               }
+#endif
        return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
        }
 
index d8734f9..e1bacbe 100644 (file)
@@ -110,8 +110,12 @@ static ERR_STRING_DATA RSA_str_functs[]=
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931),       "RSA_padding_check_X931"},
 {ERR_FUNC(RSA_F_RSA_PRINT),    "RSA_print"},
 {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
+{ERR_FUNC(RSA_F_RSA_PRIVATE_DECRYPT),  "RSA_private_decrypt"},
+{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT),  "RSA_private_encrypt"},
 {ERR_FUNC(RSA_F_RSA_PRIV_DECODE),      "RSA_PRIV_DECODE"},
 {ERR_FUNC(RSA_F_RSA_PRIV_ENCODE),      "RSA_PRIV_ENCODE"},
+{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT),   "RSA_public_decrypt"},
+{ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT),   "RSA_public_encrypt"},
 {ERR_FUNC(RSA_F_RSA_PUB_DECODE),       "RSA_PUB_DECODE"},
 {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING),   "RSA_setup_blinding"},
 {ERR_FUNC(RSA_F_RSA_SIGN),     "RSA_sign"},
@@ -158,6 +162,7 @@ static ERR_STRING_DATA RSA_str_reasons[]=
 {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL)    ,"key size too small"},
 {ERR_REASON(RSA_R_LAST_OCTET_INVALID)    ,"last octet invalid"},
 {ERR_REASON(RSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
+{ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD)   ,"non fips rsa method"},
 {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT)    ,"no public exponent"},
 {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
 {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q)  ,"n does not equal p q"},
index 3225570..e844395 100644 (file)
 #include <openssl/engine.h>
 #endif
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
 
 static const RSA_METHOD *default_RSA_meth=NULL;
@@ -93,7 +97,12 @@ const RSA_METHOD *RSA_get_default_method(void)
 #if 0 /* was: #ifdef RSAref */
                default_RSA_meth=RSA_PKCS1_RSAref();
 #else
-               default_RSA_meth=RSA_PKCS1_SSLeay();
+#ifdef OPENSSL_FIPS
+               if (FIPS_mode())
+                       default_RSA_meth = FIPS_rsa_pkcs1_ssleay();
+               else
+#endif
+                       default_RSA_meth=RSA_PKCS1_SSLeay();
 #endif
 #endif
                }
@@ -181,7 +190,7 @@ RSA *RSA_new_method(ENGINE *engine)
        ret->blinding=NULL;
        ret->mt_blinding=NULL;
        ret->bignum_data=NULL;
-       ret->flags=ret->meth->flags;
+       ret->flags=ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
        if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
                {
 #ifndef OPENSSL_NO_ENGINE
index 0be4ec7..2ccadb7 100644 (file)
@@ -77,6 +77,14 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
        const unsigned char *s = NULL;
        X509_ALGOR algor;
        ASN1_OCTET_STRING digest;
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+                       && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD);
+               return 0;
+               }
+#endif
        if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
                {
                return rsa->meth->rsa_sign(type, m, m_len,
@@ -153,6 +161,15 @@ int int_rsa_verify(int dtype, const unsigned char *m,
        unsigned char *s;
        X509_SIG *sig=NULL;
 
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
+                       && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD);
+               return 0;
+               }
+#endif
+
        if (siglen != (unsigned int)RSA_size(rsa))
                {
                RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);