Block low level public key signature operations in FIPS mode.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 6 Apr 2007 00:30:24 +0000 (00:30 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 6 Apr 2007 00:30:24 +0000 (00:30 +0000)
Update self tests for all modes and use EVP.

Update pairwise consistency checks.

24 files changed:
CHANGES
apps/dgst.c
crypto/dsa/dsa.h
crypto/dsa/dsa_asn1.c
crypto/dsa/dsa_err.c
crypto/dsa/dsa_lib.c
crypto/dsa/dsa_sign.c
crypto/dsa/dsa_vrf.c
crypto/fips_err.h
crypto/rsa/rsa.h
crypto/rsa/rsa_eng.c
crypto/rsa/rsa_err.c
crypto/rsa/rsa_lib.c
crypto/rsa/rsa_sign.c
fips-1.0/dsa/fips_dsa_key.c
fips-1.0/dsa/fips_dsa_ossl.c
fips-1.0/fips.c
fips-1.0/fips.h
fips-1.0/fips_locl.h
fips-1.0/fips_test_suite.c
fips-1.0/rsa/fips_rsa_eay.c
fips-1.0/rsa/fips_rsa_gen.c
fips-1.0/rsa/fips_rsa_selftest.c
fips-1.0/rsa/fips_rsa_sign.c

diff --git a/CHANGES b/CHANGES
index 221ce1efd89370b230ff617ddbdd229e4867d7a1..242bd7139180982f18f2e1cc1890831370613ed7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,15 @@
 
  Changes between 0.9.8e and 0.9.8f-fips  [xx XXX xxxx]
 
+  *) Rewrite self tests and pairwise tests to use EVP. Add more extensive
+     self tests for RSA in all digests and modes.
+     [Steve Henson]
+
+  *) New flags RSA_FIPS_METHOD and DSA_FIPS_METHOD to indicate a method is
+     allowed in FIPS mode. Disable direct low level RSA and DSA signature
+     operations in FIPS mode so all operations have to be made via EVP.
+     [Steve Henson]
+
   *) New flag EVP_MD_FLAG_SVCTX which passes EVP_MD_CTX and key to underlying
      sign/verify method. This permits the method to perform finalization
      and signing itself and have access to the EVP_MD_CTX structure in case
index 91d5c196cb85bef8572f9a73413a84c878e84de7..72ff877afb250c09f7ccf782f32148fdda92e1b7 100644 (file)
@@ -101,6 +101,7 @@ int MAIN(int argc, char **argv)
        EVP_PKEY *sigkey = NULL;
        unsigned char *sigbuf = NULL;
        int siglen = 0;
+       unsigned int sig_flags = 0;
        char *passargin = NULL, *passin = NULL;
 #ifndef OPENSSL_NO_ENGINE
        char *engine=NULL;
@@ -168,6 +169,27 @@ ERR_load_crypto_strings();
                        keyfile=*(++argv);
                        do_verify = 1;
                        }
+               else if (strcmp(*argv,"-x931") == 0)
+                       sig_flags = EVP_MD_CTX_FLAG_PAD_X931;
+               else if (strcmp(*argv,"-pss_saltlen") == 0)
+                       {
+                       int saltlen;
+                       if (--argc < 1) break;
+                       saltlen=atoi(*(++argv));
+                       if (saltlen == -1)
+                               sig_flags = EVP_MD_CTX_FLAG_PSS_MREC;
+                       else if (saltlen == -2)
+                               sig_flags = EVP_MD_CTX_FLAG_PSS_MDLEN;
+                       else if (saltlen < -2 || saltlen >= 0xFFFE)
+                               {
+                               BIO_printf(bio_err, "Invalid PSS salt length %d\n", saltlen);
+                               goto end;
+                               }
+                       else
+                               sig_flags = saltlen;
+                       sig_flags <<= 16;
+                       sig_flags |= EVP_MD_CTX_FLAG_PAD_PSS;
+                       }
                else if (strcmp(*argv,"-signature") == 0)
                        {
                        if (--argc < 1) break;
@@ -360,6 +382,12 @@ ERR_load_crypto_strings();
                EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
                }
 
+       if (sig_flags)
+               {
+               EVP_MD_CTX *md_ctx;
+               BIO_get_md_ctx(bmd,&md_ctx);
+               EVP_MD_CTX_set_flags(md_ctx, sig_flags);
+               }
 
        /* we use md as a filter, reading from 'in' */
        if (!BIO_set_md(bmd,md))
index 3b4c636d06f969874448d94b71c4e535c3ac7112..914f6c719531d78cd4e9c51cd466930cb0be0490 100644 (file)
                                               * be used for all exponents.
                                               */
 
-/* If this flag is set external DSA_METHOD callbacks are allowed in FIPS mode
- * it is then the applications responsibility to ensure the external method
- * is compliant.
+/* 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_EXTERNAL_METHOD_ALLOW    0x04
+#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 OPENSSL_FIPS
 #define FIPS_DSA_SIZE_T        int
@@ -287,6 +295,8 @@ void ERR_load_DSA_strings(void);
 #define DSA_F_DSA_NEW_METHOD                            103
 #define DSA_F_DSA_PRINT                                         104
 #define DSA_F_DSA_PRINT_FP                              105
+#define DSA_F_DSA_SET_DEFAULT_METHOD                    115
+#define DSA_F_DSA_SET_METHOD                            116
 #define DSA_F_DSA_SIGN                                  106
 #define DSA_F_DSA_SIGN_SETUP                            107
 #define DSA_F_DSA_SIG_NEW                               109
@@ -299,6 +309,8 @@ void ERR_load_DSA_strings(void);
 #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE               100
 #define DSA_R_MISSING_PARAMETERS                        101
 #define DSA_R_MODULUS_TOO_LARGE                                 103
+#define DSA_R_NON_FIPS_METHOD                           104
+#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE        105
 
 #ifdef  __cplusplus
 }
index be8913d1e7a4339c992ef7c3ef9ac294097957f5..0d10b0353e5ff8df87f437e5a081c20013e711fd 100644 (file)
@@ -61,6 +61,7 @@
 #include <openssl/dsa.h>
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
+#include <openssl/fips.h>
 
 /* Override the default new methods */
 static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
@@ -143,6 +144,13 @@ int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
             unsigned int *siglen, DSA *dsa)
        {
        DSA_SIG *s;
+#ifdef OPENSSL_FIPS
+       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+               return 0;
+               }
+#endif
        s=DSA_do_sign(dgst,dlen,dsa);
        if (s == NULL)
                {
@@ -187,6 +195,13 @@ int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
        {
        DSA_SIG *s;
        int ret=-1;
+#ifdef OPENSSL_FIPS
+       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+               return 0;
+               }
+#endif
 
        s = DSA_SIG_new();
        if (s == NULL) return(ret);
index 768711994b9cc05912e58c98906deb71018e0583..68663d85fdb08bdd3e6a23fe4717ed9b97640c0e 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/dsa/dsa_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 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
@@ -78,6 +78,8 @@ static ERR_STRING_DATA DSA_str_functs[]=
 {ERR_FUNC(DSA_F_DSA_NEW_METHOD),       "DSA_new_method"},
 {ERR_FUNC(DSA_F_DSA_PRINT),    "DSA_print"},
 {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
+{ERR_FUNC(DSA_F_DSA_SET_DEFAULT_METHOD),       "DSA_set_default_method"},
+{ERR_FUNC(DSA_F_DSA_SET_METHOD),       "DSA_set_method"},
 {ERR_FUNC(DSA_F_DSA_SIGN),     "DSA_sign"},
 {ERR_FUNC(DSA_F_DSA_SIGN_SETUP),       "DSA_sign_setup"},
 {ERR_FUNC(DSA_F_DSA_SIG_NEW),  "DSA_SIG_new"},
@@ -93,6 +95,8 @@ static ERR_STRING_DATA DSA_str_reasons[]=
 {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
 {ERR_REASON(DSA_R_MISSING_PARAMETERS)    ,"missing parameters"},
 {ERR_REASON(DSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
+{ERR_REASON(DSA_R_NON_FIPS_METHOD)       ,"non fips method"},
+{ERR_REASON(DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
 {0,NULL}
        };
 
index 3198ef94b30f36bb57425fb0f4f3a66e5358e4a6..7ac9dc8c8920d0ae3894d098aa24b377a188292c 100644 (file)
@@ -76,6 +76,14 @@ static const DSA_METHOD *default_DSA_method = NULL;
 
 void DSA_set_default_method(const DSA_METHOD *meth)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
+               {
+               DSAerr(DSA_F_DSA_SET_DEFAULT_METHOD, DSA_R_NON_FIPS_METHOD);
+               return;
+               }
+#endif
+               
        default_DSA_method = meth;
        }
 
@@ -96,6 +104,13 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
        /* NB: The caller is specifically setting a method, so it's not up to us
         * to deal with which ENGINE it comes from. */
         const DSA_METHOD *mtmp;
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
+               {
+               DSAerr(DSA_F_DSA_SET_METHOD, DSA_R_NON_FIPS_METHOD);
+               return 0;
+               }
+#endif
         mtmp = dsa->meth;
         if (mtmp->finish) mtmp->finish(dsa);
 #ifndef OPENSSL_NO_ENGINE
@@ -147,6 +162,18 @@ DSA *DSA_new_method(ENGINE *engine)
                        }
                }
 #endif
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD))
+               {
+               DSAerr(DSA_F_DSA_NEW_METHOD, DSA_R_NON_FIPS_METHOD);
+#ifndef OPENSSL_NO_ENGINE
+               if (ret->engine)
+                       ENGINE_finish(ret->engine);
+#endif
+               OPENSSL_free(ret);
+               return NULL;
+               }
+#endif
 
        ret->pad=0;
        ret->version=0;
index ff181aff9ebac052e0305869940f12f76aed596a..4fd22283c5fc0eab9484ca198db3ab1d5d57299b 100644 (file)
 DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
        {
 #ifdef OPENSSL_FIPS
-       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_FIPS_EXTERNAL_METHOD_ALLOW)
-               && !FIPS_dsa_check(dsa))
+       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
                return NULL;
+               }
 #endif
        return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
        }
@@ -79,9 +81,11 @@ DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
 int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
        {
 #ifdef OPENSSL_FIPS
-       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_FIPS_EXTERNAL_METHOD_ALLOW)
-               && !FIPS_dsa_check(dsa))
+       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
                return 0;
+               }
 #endif
        return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
        }
index d2796d4e0c9836aea15ae0126ac0f62f7458bd09..dcceed2f8ed514f1638564f9ef4f796bdbfea33a 100644 (file)
@@ -71,9 +71,11 @@ int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
                  DSA *dsa)
        {
 #ifdef OPENSSL_FIPS
-       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_FIPS_EXTERNAL_METHOD_ALLOW)
-               && !FIPS_dsa_check(dsa))
-               return -1;
+       if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+               {
+               DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+               return 0;
+               }
 #endif
        return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
        }
index 96afed905e89f65f0139a6c1501997cd05d68ce7..9c07e9f7259da2b0c9cd8ec0d77beba70636fb76 100644 (file)
@@ -78,9 +78,11 @@ static ERR_STRING_DATA FIPS_str_functs[]=
 {ERR_FUNC(FIPS_F_FIPS_CHECK_DSO),      "FIPS_CHECK_DSO"},
 {ERR_FUNC(FIPS_F_FIPS_CHECK_EXE),      "FIPS_CHECK_EXE"},
 {ERR_FUNC(FIPS_F_FIPS_CHECK_FINGERPRINT),      "FIPS_CHECK_FINGERPRINT"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_PK_SIG),   "FIPS_CHECK_PK_SIG"},
 {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA),      "FIPS_CHECK_RSA"},
 {ERR_FUNC(FIPS_F_FIPS_DSA_CHECK),      "FIPS_dsa_check"},
 {ERR_FUNC(FIPS_F_FIPS_MODE_SET),       "FIPS_mode_set"},
+{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST),    "fips_pkey_signature_test"},
 {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES),   "FIPS_selftest_aes"},
 {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES),   "FIPS_selftest_des"},
 {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA),   "FIPS_selftest_dsa"},
@@ -113,6 +115,7 @@ static ERR_STRING_DATA FIPS_str_reasons[]=
 {ERR_REASON(FIPS_R_RSA_DECRYPT_ERROR)    ,"rsa decrypt error"},
 {ERR_REASON(FIPS_R_RSA_ENCRYPT_ERROR)    ,"rsa encrypt error"},
 {ERR_REASON(FIPS_R_SELFTEST_FAILED)      ,"selftest failed"},
+{ERR_REASON(FIPS_R_TEST_FAILURE)         ,"test failure"},
 {ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"},
 {0,NULL}
        };
index e36397bd5f7b9a8a68b10e18eada71b388ffc92e..464b295f0dcd43c58086042a74b3b9bdee60eae1 100644 (file)
 #error RSA is disabled.
 #endif
 
+/* 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 reposibility
+ * 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
+
 #ifdef OPENSSL_FIPS
 #define FIPS_RSA_SIZE_T        int
 #endif
@@ -420,7 +435,10 @@ 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_ENCRYPT                       137
+#define RSA_F_RSA_PUBLIC_DECRYPT                        138
 #define RSA_F_RSA_SETUP_BLINDING                        136
+#define RSA_F_RSA_SET_DEFAULT_METHOD                    139
 #define RSA_F_RSA_SIGN                                  117
 #define RSA_F_RSA_SIGN_ASN1_OCTET_STRING                118
 #define RSA_F_RSA_VERIFY                                119
@@ -454,10 +472,12 @@ 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_METHOD                           141
 #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
 #define RSA_R_OAEP_DECODING_ERROR                       121
+#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE        142
 #define RSA_R_PADDING_CHECK_FAILED                      114
 #define RSA_R_P_NOT_PRIME                               128
 #define RSA_R_Q_NOT_PRIME                               129
index ce7157ffa448eda7c35012fe9b7abe19cf364121..03410423ff4d6c83acec08c7b65eed8482edd882 100644 (file)
@@ -80,6 +80,13 @@ RSA *RSA_new(void)
 
 void RSA_set_default_method(const RSA_METHOD *meth)
        {
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
+               {
+               RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
+               return;
+               }
+#endif
        default_RSA_meth = meth;
        }
 
@@ -111,6 +118,13 @@ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
        /* NB: The caller is specifically setting a method, so it's not up to us
         * to deal with which ENGINE it comes from. */
        const RSA_METHOD *mtmp;
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
+               {
+               RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
+               return 0;
+               }
+#endif
        mtmp = rsa->meth;
        if (mtmp->finish) mtmp->finish(rsa);
 #ifndef OPENSSL_NO_ENGINE
@@ -163,6 +177,18 @@ RSA *RSA_new_method(ENGINE *engine)
                        }
                }
 #endif
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD))
+               {
+               RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
+#ifndef OPENSSL_NO_ENGINE
+               if (ret->engine)
+                       ENGINE_finish(ret->engine);
+#endif
+               OPENSSL_free(ret);
+               return NULL;
+               }
+#endif
 
        ret->pad=0;
        ret->version=0;
index fe3ba1b44bbdafd094dc633d940fda77a2e3292a..69a5db945931282c94ec84b2c91f4c2f5647b7be 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/rsa/rsa_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 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
@@ -101,7 +101,10 @@ 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_ENCRYPT),  "RSA_private_encrypt"},
+{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT),   "RSA_public_decrypt"},
 {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING),   "RSA_setup_blinding"},
+{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD),       "RSA_set_default_method"},
 {ERR_FUNC(RSA_F_RSA_SIGN),     "RSA_sign"},
 {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),   "RSA_sign_ASN1_OCTET_STRING"},
 {ERR_FUNC(RSA_F_RSA_VERIFY),   "RSA_verify"},
@@ -138,10 +141,12 @@ 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_METHOD)       ,"non fips 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"},
 {ERR_REASON(RSA_R_OAEP_DECODING_ERROR)   ,"oaep decoding error"},
+{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
 {ERR_REASON(RSA_R_PADDING_CHECK_FAILED)  ,"padding check failed"},
 {ERR_REASON(RSA_R_P_NOT_PRIME)           ,"p not prime"},
 {ERR_REASON(RSA_R_Q_NOT_PRIME)           ,"q not prime"},
index 5adb05e022279a7bb283e1fba57fdd3330b6b5ef..5714841f4cabf24d48833f20d440153eae6735c3 100644 (file)
@@ -76,6 +76,13 @@ int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
 int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
             RSA *rsa, int padding)
        {
+#ifdef OPENSSL_FIPS
+       if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+               return 0;
+               }
+#endif
        return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
        }
 
@@ -88,6 +95,13 @@ int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
 int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
             RSA *rsa, int padding)
        {
+#ifdef OPENSSL_FIPS
+       if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+               return 0;
+               }
+#endif
        return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
        }
 
index 71aabeea1bd73bca46c8a1657273dbedbffad4e0..5488c06f6d8d9df23c756eaf5f4417aab60693b1 100644 (file)
@@ -90,6 +90,14 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
                i = SSL_SIG_LENGTH;
                s = m;
        } else {
+       /* NB: in FIPS mode block anything that isn't a TLS signature */
+#ifdef OPENSSL_FIPS
+               if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+                       {
+                       RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+                       return 0;
+                       }
+#endif
                sig.algor= &algor;
                sig.algor->algorithm=OBJ_nid2obj(type);
                if (sig.algor->algorithm == NULL)
@@ -167,10 +175,22 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
                RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
                goto err;
                }
-       if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
+       if(dtype == NID_md5_sha1)
+               {
+               if (m_len != SSL_SIG_LENGTH)
+                       {
                        RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
                        goto err;
-       }
+                       }
+               }
+       /* NB: in FIPS mode block anything that isn't a TLS signature */
+#ifdef OPENSSL_FIPS
+       else if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+               {
+               RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+               return 0;
+               }
+#endif
        i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
 
        if (i <= 0) goto err;
index 9940d139fc576c0e1a3b63a8269cef887499916b..05c06ab67d3405026d8f0ebac4b18e4d7645fe08 100644 (file)
 #include <openssl/dsa.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
+#include <openssl/evp.h>
 #include <openssl/fips.h>
 
 #ifdef OPENSSL_FIPS
 
 static int dsa_builtin_keygen(DSA *dsa);
 
-static int fips_check_dsa(DSA *dsa)
-    {
-    static const unsigned char str1[]="12345678901234567890";
-    int r = 0;
-    DSA_SIG *sig;
-
-    sig = DSA_do_sign(str1, 20, dsa);
-
-    if (sig)
+int fips_check_dsa(DSA *dsa)
        {
-       r = DSA_do_verify(str1, 20, sig, dsa);
-       DSA_SIG_free(sig);
-       }
+       EVP_PKEY pk;
+       unsigned char tbs[] = "DSA Pairwise Check Data";
+       pk.type = EVP_PKEY_DSA;
+       pk.pkey.dsa = dsa;
 
-    if(r != 1)
-       {
-       FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
-       return 0;
+       if (!fips_pkey_signature_test(&pk, tbs, -1,
+                                       NULL, 0, EVP_dss1(), 0, NULL))
+               {
+               FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
+               return 0;
+               }
+       return 1;
        }
-    return 1;
-    }
 
 int DSA_generate_key(DSA *dsa)
        {
index eec80af364a26d810c43064695bb755db23b10ff..c00a9c4c89756af023b63b9332965431f2504f86 100644 (file)
@@ -92,10 +92,10 @@ dsa_mod_exp,
 dsa_bn_mod_exp,
 dsa_init,
 dsa_finish,
-0,
+DSA_FLAG_FIPS_METHOD,
 NULL
 };
-
+#if 0
 int FIPS_dsa_check(struct dsa_st *dsa)
     {
     if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign
@@ -110,6 +110,7 @@ int FIPS_dsa_check(struct dsa_st *dsa)
        }
     return 1;
     }
+#endif
 
 const DSA_METHOD *DSA_OpenSSL(void)
 {
@@ -153,7 +154,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA
        ctx=BN_CTX_new();
        if (ctx == NULL) goto err;
 
-       if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+       if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err;
 
        if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
 
index 9f0e69842eee84b67b342f100d6bcd7f5532f2c0..f75ea4661fce31a7a51323f0d9f0df59a10c01c6 100644 (file)
@@ -53,6 +53,7 @@
 #include <openssl/err.h>
 #include <openssl/bio.h>
 #include <openssl/hmac.h>
+#include <openssl/rsa.h>
 #include <string.h>
 #include <limits.h>
 #include "fips_locl.h"
@@ -381,4 +382,71 @@ unsigned char *fips_signature_witness(void)
        return FIPS_signature;
        }
 
+/* Generalized public key test routine. Signs and verifies the data
+ * supplied in tbs using mesage digest md and setting option digest
+ * flags md_flags. If the 'kat' parameter is not NULL it will
+ * additionally check the signature matches it: a known answer test
+ * The string "fail_str" is used for identification purposes in case
+ * of failure.
+ */
+
+int fips_pkey_signature_test(EVP_PKEY *pkey,
+                       const unsigned char *tbs, int tbslen,
+                       const unsigned char *kat, unsigned int katlen,
+                       const EVP_MD *digest, unsigned int md_flags,
+                       const char *fail_str)
+       {       
+       int ret = 0;
+       unsigned char sigtmp[256], *sig = sigtmp;
+       unsigned int siglen;
+       EVP_MD_CTX mctx;
+       EVP_MD_CTX_init(&mctx);
+
+       if ((pkey->type == EVP_PKEY_RSA)
+               && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp)))
+               {
+               sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa));
+               if (!sig)
+                       {
+                       FIPSerr(FIPS_F_FIPS_CHECK_PK_SIG,ERR_R_MALLOC_FAILURE);
+                       return 0;
+                       }
+               }
+
+       if (tbslen == -1)
+               tbslen = strlen((char *)tbs);
+
+       if (md_flags)
+               M_EVP_MD_CTX_set_flags(&mctx, md_flags);
+
+       if (!EVP_SignInit_ex(&mctx, digest, NULL))
+               goto error;
+       if (!EVP_SignUpdate(&mctx, tbs, tbslen))
+               goto error;
+       if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
+               goto error;
+
+       if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
+               goto error;
+
+       if (!EVP_VerifyInit_ex(&mctx, digest, NULL))
+               goto error;
+       if (!EVP_VerifyUpdate(&mctx, tbs, tbslen))
+               goto error;
+       ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
+
+       error:
+       if (sig != sigtmp)
+               OPENSSL_free(sig);
+       EVP_MD_CTX_cleanup(&mctx);
+       if (ret != 1)
+               {
+               FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE);
+               if (fail_str)
+                       ERR_add_error_data(2, "Type=", fail_str);
+               return 0;
+               }
+       return 1;
+       }
+
 #endif
index 690149bc4f25d6d10271a2700a07e8e36bfdbda8..bf810dfa8c1e6c1bfbef6feb1c43fa0c940999aa 100644 (file)
@@ -56,6 +56,8 @@ extern "C" {
 #endif
 
 struct dsa_st;
+struct evp_pkey_st;
+struct env_md_st;
 
 int FIPS_mode_set(int onoff);
 int FIPS_mode(void);
@@ -76,6 +78,12 @@ void FIPS_corrupt_rng(void);
 int FIPS_selftest_rng(void);
 int FIPS_selftest_hmac(void);
 
+int fips_pkey_signature_test(struct evp_pkey_st *pkey,
+                       const unsigned char *tbs, int tbslen,
+                       const unsigned char *kat, unsigned int katlen,
+                       const struct env_md_st *digest, unsigned int md_flags,
+                       const char *fail_str);
+
 /* 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.
@@ -93,9 +101,11 @@ void ERR_load_FIPS_strings(void);
 #define FIPS_F_FIPS_CHECK_DSO                           120
 #define FIPS_F_FIPS_CHECK_EXE                           106
 #define FIPS_F_FIPS_CHECK_FINGERPRINT                   121
+#define FIPS_F_FIPS_CHECK_PK_SIG                        122
 #define FIPS_F_FIPS_CHECK_RSA                           115
 #define FIPS_F_FIPS_DSA_CHECK                           102
 #define FIPS_F_FIPS_MODE_SET                            105
+#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST                         123
 #define FIPS_F_FIPS_SELFTEST_AES                        104
 #define FIPS_F_FIPS_SELFTEST_DES                        107
 #define FIPS_F_FIPS_SELFTEST_DSA                        109
@@ -125,6 +135,7 @@ void ERR_load_FIPS_strings(void);
 #define FIPS_R_RSA_DECRYPT_ERROR                        115
 #define FIPS_R_RSA_ENCRYPT_ERROR                        116
 #define FIPS_R_SELFTEST_FAILED                          101
+#define FIPS_R_TEST_FAILURE                             117
 #define FIPS_R_UNSUPPORTED_PLATFORM                     113
 
 #ifdef  __cplusplus
index bbddfaab8275ee6092b54258a9a8812a2f79ea50..cc91341beed2a58f49d1e6abdf46e1c4f9f0a0ba 100644 (file)
@@ -53,7 +53,6 @@
 extern "C" {
 #endif
 
-/* These are trampolines implemented in crypto/cryptlib.c */
 void fips_w_lock(void);
 void fips_w_unlock(void);
 void fips_r_lock(void);
index 5e8a279c8d16238068e95d03f0e462c8b08cf707..856599aa32933ce24c1e4fd26232a6148e21df4e 100644 (file)
@@ -82,49 +82,69 @@ static int FIPS_des_test()
     return 1;
     }
 
-/* DSA: generate key and sign a known digest, then verify the signature
- * against the digest
-*/
+/*
+ * DSA: generate keys and sign, verify input plaintext.
+ */
 static int FIPS_dsa_test()
     {
     DSA *dsa = NULL;
+    EVP_PKEY pk;
     unsigned char dgst[] = "etaonrishdlc";
-    DSA_SIG *sig = NULL;
+    unsigned char buf[60];
+    unsigned int slen;
     int r = 0;
+    EVP_MD_CTX mctx;
 
     ERR_clear_error();
+    EVP_MD_CTX_init(&mctx);
     dsa = FIPS_dsa_new();
     if (!dsa)
-       return 0;
+       goto end;
     if (!DSA_generate_parameters_ex(dsa, 512,NULL,0,NULL,NULL,NULL))
-       return 0;
+       goto end;
     if (!DSA_generate_key(dsa))
-       return 0;
-    sig = DSA_do_sign(dgst,sizeof(dgst) - 1,dsa);
-    if (sig)
-       {
-       r = DSA_do_verify(dgst,sizeof(dgst) - 1,sig,dsa);
-       DSA_SIG_free(sig);
-       }
+       goto end;
+
+    pk.type = EVP_PKEY_DSA;
+    pk.pkey.dsa = dsa;
+
+    if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
+       goto end;
+    if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1))
+       goto end;
+    if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+       goto end;
+
+    if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
+       goto end;
+    if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1))
+       goto end;
+    r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
+    end:
+    EVP_MD_CTX_cleanup(&mctx);
+    if (dsa)
+         FIPS_dsa_free(dsa);
     if (r != 1)
        return 0;
-    FIPS_dsa_free(dsa);
     return 1;
     }
 
-/* RSA: generate keys and encrypt and decrypt known plaintext, verify result
- * matches the original plaintext
-*/
+/*
+ * RSA: generate keys and sign, verify input plaintext.
+ */
 static int FIPS_rsa_test()
     {
     RSA *key;
     unsigned char input_ptext[] = "etaonrishdlc";
-    unsigned char ctext[256];
-    unsigned char ptext[256];
+    unsigned char buf[256];
+    unsigned int slen;
     BIGNUM *bn;
-    int n;
+    EVP_MD_CTX mctx;
+    EVP_PKEY pk;
+    int r;
 
     ERR_clear_error();
+    EVP_MD_CTX_init(&mctx);
     key = FIPS_rsa_new();
     bn = BN_new();
     if (!key || !bn)
@@ -133,16 +153,28 @@ static int FIPS_rsa_test()
     if (!RSA_generate_key_ex(key, 1024,bn,NULL))
        return 0;
     BN_free(bn);
-    n = RSA_size(key);
-    n = RSA_public_encrypt(sizeof(input_ptext) - 1,input_ptext,ctext,key,RSA_PKCS1_PADDING);
-    if (n < 0)
-       return 0;
-    n = RSA_private_decrypt(n,ctext,ptext,key,RSA_PKCS1_PADDING);
-    if (n < 0)
+
+    pk.type = EVP_PKEY_RSA;
+    pk.pkey.rsa = key;
+
+    if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL))
+       goto end;
+    if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
+       goto end;
+    if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+       goto end;
+
+    if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL))
+       goto end;
+    if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
+       goto end;
+    r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
+    end:
+    EVP_MD_CTX_cleanup(&mctx);
+    if (key)
+         FIPS_rsa_free(key);
+    if (r != 1)
        return 0;
-    FIPS_rsa_free(key);
-    if (memcmp(input_ptext,ptext,sizeof(input_ptext) - 1))
-        return 0;
     return 1;
     }
 
index 69fdb8380a1b8572052bcb66e458aab487b1e63d..45b3bd1b1a289415d8b4c14e0711cc1fc2ac9820 100644 (file)
@@ -139,7 +139,7 @@ static RSA_METHOD rsa_pkcs1_eay_meth={
        BN_mod_exp_mont, /* XXX probably we should not use Montgomery if  e == 3 */
        RSA_eay_init,
        RSA_eay_finish,
-       0, /* flags */
+       RSA_FLAG_FIPS_METHOD, /* flags */
        NULL,
        0, /* rsa_sign */
        0, /* rsa_verify */
index 7d9d78d5cc90c9731feb9215080e8f5d0a064c65..7c23ef8357ddf167d37b220617fe408c0f4deab0 100644 (file)
 #include <stdio.h>
 #include <time.h>
 #include <string.h>
+#include <openssl/crypto.h>
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
 #include <openssl/err.h>
+#include <openssl/evp.h>
 #include <openssl/fips.h>
 
 #ifdef OPENSSL_FIPS
 
 int fips_check_rsa(RSA *rsa)
-    {
-    int n, ret = 0;
-    unsigned char tctext[256], *ctext = tctext;
-    unsigned char tptext[256], *ptext = tptext;
-    /* The longest we can have with PKCS#1 v1.5 padding and a 512 bit key,
-     * namely 512/8-11-1 = 52 bytes */
-    static const unsigned char original_ptext[] =
-       "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
-       "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
-       "\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
-       "\x01\x23\x45\x67";
-
-    if (RSA_size(rsa) > sizeof(tctext))
        {
-       ctext = OPENSSL_malloc(RSA_size(rsa));
-       ptext = OPENSSL_malloc(RSA_size(rsa));
-       if (!ctext || !ptext)
+       const unsigned char tbs[] = "RSA Pairwise Check Data";
+       EVP_PKEY pk;
+       pk.type = EVP_PKEY_RSA;
+       pk.pkey.rsa = rsa;
+
+       if (!fips_pkey_signature_test(&pk, tbs, -1,
+                       NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, NULL)
+               || !fips_pkey_signature_test(&pk, tbs, -1,
+                       NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, NULL)
+               || !fips_pkey_signature_test(&pk, tbs, -1,
+                       NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, NULL))
                {
-               FIPSerr(FIPS_F_FIPS_CHECK_RSA,ERR_R_MALLOC_FAILURE);
-               goto error;
+               FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
+               return 0;
                }
+       return 1;
        }
-       
-
-    /* this will fail for keys shorter than 512 bits */
-    n=RSA_private_encrypt(sizeof(original_ptext)-1,original_ptext,ctext,rsa,
-                        RSA_PKCS1_PADDING);
-    if(n < 0)
-       {
-       FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_RSA_ENCRYPT_ERROR);
-       goto error;
-       }
-    if(!memcmp(ctext,original_ptext,n))
-       {
-       FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
-       goto error;
-       }
-    n=RSA_public_decrypt(n,ctext,ptext,rsa,RSA_PKCS1_PADDING);
-    if(n < 0)
-       {
-       FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_RSA_DECRYPT_ERROR);
-       goto error;
-       }
-    if(n != sizeof(original_ptext)-1 || memcmp(ptext,original_ptext,n))
-       {
-       FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
-       goto error;
-       }
-
-    ret = 1;
-
-    error:
-
-    if (RSA_size(rsa) > sizeof(tctext))
-       {
-       OPENSSL_free(ctext);
-       OPENSSL_free(ptext);
-       }
-
-    return ret;
-    }
 
 static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
 
index 7fd0ccb962e344f4bf530e1e219fffb0493b5b47..4cd4a1da0fd1b331470f7ee100a1adee3dadbe01 100644 (file)
@@ -1,5 +1,5 @@
 /* ====================================================================
- * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2003-2007 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
@@ -51,6 +51,7 @@
 #include <openssl/err.h>
 #include <openssl/fips.h>
 #include <openssl/rsa.h>
+#include <openssl/evp.h>
 #include <openssl/fips_sha.h>
 #include <openssl/opensslconf.h>
 
@@ -68,7 +69,7 @@ static unsigned char n[] =
 "\xCB";
 
 
-static int setrsakey(RSA *key, unsigned char *c)
+static int setrsakey(RSA *key)
     {
     static const unsigned char e[] = "\x11";
 
@@ -116,16 +117,6 @@ static int setrsakey(RSA *key, unsigned char *c)
 "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
 "\xF7";
 
-    static const unsigned char ctext_ex[] =
-"\x42\x4b\xc9\x51\x61\xd4\xca\xa0\x18\x6c\x4d\xca\x61\x8f\x2d\x07"
-"\x8c\x63\xc5\x6b\xa2\x4c\x32\xb1\xda\xb7\xdd\x32\xb6\x51\x68\xc3"
-"\x6e\x98\x46\xd6\xbb\x1a\xd5\x99\x05\x92\x7c\xd7\xbc\x08\x9e\xe4"
-"\xc3\x70\x4d\xe6\x99\x7e\x61\x31\x07\x7a\x19\xdb\x3e\x11\xfa\x3d"
-"\x7c\x61\xd7\x78\x14\x3f\x05\x16\xa0\xc4\xbf\xcd\xee\xca\x67\x4c"
-"\x80\x4e\xca\x43\x2f\x35\x43\x58\xa7\x50\x7e\x3e\x52\x82\xab\xac"
-"\xa6\x50\xe8\x39\x9f\xe0\x7f\x58\x1d\x1b\x90\x93\x04\xec\xb3\xf9"
-"\x24\xd3\x75\x3e\x39\xd1\x14\xc6\x33\xce\xd6\xee\x20\x47\xec\xe4";
-
     key->n = BN_bin2bn(n, sizeof(n)-1, key->n);
     key->e = BN_bin2bn(e, sizeof(e)-1, key->e);
     key->d = BN_bin2bn(d, sizeof(d)-1, key->d);
@@ -134,9 +125,7 @@ static int setrsakey(RSA *key, unsigned char *c)
     key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1);
     key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1);
     key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp);
-    memcpy(c, ctext_ex, sizeof(ctext_ex) - 1);
-    return (sizeof(ctext_ex) - 1);
-
+    return 1;
     }
 
 void FIPS_corrupt_rsa()
@@ -144,110 +133,300 @@ void FIPS_corrupt_rsa()
     n[0]++;
     }
 
+/* Known Answer Test (KAT) data for the above RSA private key signing
+ * kat_tbs.
+ */
+
+static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";
+
+static const unsigned char kat_RSA_PSS_SHA1[] = {
+  0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F,
+  0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB,
+  0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3,
+  0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C,
+  0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7,
+  0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5,
+  0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45,
+  0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31,
+  0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8,
+  0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84,
+  0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9
+};
+
+static const unsigned char kat_RSA_PSS_SHA224[] = {
+  0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7,
+  0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA,
+  0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57,
+  0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89,
+  0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE,
+  0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22,
+  0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5,
+  0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49,
+  0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D,
+  0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00,
+  0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0
+};
+
+static const unsigned char kat_RSA_PSS_SHA256[] = {
+  0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89,
+  0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F,
+  0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28,
+  0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E,
+  0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05,
+  0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA,
+  0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6,
+  0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F,
+  0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D,
+  0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6,
+  0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C
+};
+
+static const unsigned char kat_RSA_PSS_SHA384[] = {
+  0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2,
+  0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E,
+  0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD,
+  0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F,
+  0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C,
+  0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB,
+  0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F,
+  0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89,
+  0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F,
+  0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55,
+  0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1
+};
+
+static const unsigned char kat_RSA_PSS_SHA512[] = {
+  0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C,
+  0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A,
+  0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD,
+  0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39,
+  0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7,
+  0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61,
+  0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13,
+  0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63,
+  0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE,
+  0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88,
+  0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B
+};
+
+static const unsigned char kat_RSA_SHA1[] = {
+  0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C,
+  0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B,
+  0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF,
+  0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,
+  0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1,
+  0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA,
+  0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E,
+  0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,
+  0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F,
+  0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95,
+  0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4
+};
+
+static const unsigned char kat_RSA_SHA224[] = {
+  0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9,
+  0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D,
+  0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89,
+  0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD,
+  0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5,
+  0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC,
+  0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B,
+  0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2,
+  0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35,
+  0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC,
+  0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D
+};
+
+static const unsigned char kat_RSA_SHA256[] = {
+  0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23,
+  0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23,
+  0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35,
+  0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E,
+  0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18,
+  0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30,
+  0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A,
+  0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38,
+  0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA,
+  0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90,
+  0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A
+};
+
+static const unsigned char kat_RSA_SHA384[] = {
+  0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F,
+  0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7,
+  0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C,
+  0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55,
+  0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF,
+  0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2,
+  0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C,
+  0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD,
+  0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1,
+  0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04,
+  0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF
+};
+
+static const unsigned char kat_RSA_SHA512[] = {
+  0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF,
+  0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A,
+  0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1,
+  0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8,
+  0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5,
+  0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B,
+  0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6,
+  0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05,
+  0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D,
+  0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91,
+  0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84
+};
+
+static const unsigned char kat_RSA_X931_SHA1[] = {
+  0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF,
+  0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75,
+  0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC,
+  0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97,
+  0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6,
+  0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19,
+  0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7,
+  0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99,
+  0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76,
+  0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67,
+  0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49
+};
+
+static const unsigned char kat_RSA_X931_SHA256[] = {
+  0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89,
+  0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD,
+  0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF,
+  0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B,
+  0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B,
+  0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98,
+  0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC,
+  0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C,
+  0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD,
+  0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC,
+  0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80
+};
+
+static const unsigned char kat_RSA_X931_SHA384[] = {
+  0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B,
+  0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB,
+  0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3,
+  0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6,
+  0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31,
+  0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1,
+  0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79,
+  0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF,
+  0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35,
+  0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D,
+  0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28
+};
+
+static const unsigned char kat_RSA_X931_SHA512[] = {
+  0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63,
+  0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC,
+  0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7,
+  0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28,
+  0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5,
+  0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF,
+  0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0,
+  0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09,
+  0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C,
+  0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B,
+  0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3
+};
+
+
 int FIPS_selftest_rsa()
-    {
-    int clen, ret = 0;
-    RSA *key;
-    unsigned char expected_ctext[256];
-    unsigned char ctext[256];
-    unsigned char ptext[256];
-    static const unsigned char original_ptext[] =
-       "\x01\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0"
-       "\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12"
-       "\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34"
-       "\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56"
-       "\x89\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78"
-       "\xab\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a"
-       "\xcd\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc"
-       "\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde"
-       "\xf0\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde";
-    unsigned char md[SHA_DIGEST_LENGTH];
-    static const unsigned char mdkat[SHA_DIGEST_LENGTH] =
-       "\x2d\x57\x1d\x6f\x5c\x37\xf9\xf0\x3b\xb4\x3c\xe8\x2c\x4c\xb3\x04"
-       "\x75\xa2\x0e\xfb";
-    static const unsigned char ctextkat[] =
-       "\x3e\xc5\x0a\xbe\x29\xa2\xca\x9a\x35\x14\x17\x26\xa4\x0f\xa3\x03"
-       "\x65\xb5\x37\xf5\x6a\xaa\xb\xf\x2c\x0d\x8\xc0\x73\x8\x3c\x88\x85"
-       "\x36\x68\x16\xfe\x2f\x59\x77\x7e\x2a\x76\x9a\xc7\x27\x19\x9b\x54"
-       "\x14\x87\xf3\xe0\xce\x1e\x68\x10\x40\x14\xac\xbc\xe6\x6f\x26\x1f"
-       "\x55\xd1\x15\x81\x48\x10\xf4\x89\xe5\x67\x52\x42\x87\x04\x74\x4e"
-       "\x96\x14\x7c\x53\xc9\x1e\x84\x11\x7d\x7d\x23\xbd\xff\x6c\xcb\x00"
-       "\x96\x2e\x7d\xfb\x47\xea\x78\xcd\xd8\x04\x3a\x98\x06\x13\x68\x39"
-       "\xa1\xe2\xbc\x9f\x64\xc7\x62\xf0\x74\x4d\x42\xe0\x0b\xcf\x24\x48";
-    int i;
-
-    /* Perform pairwise consistency test by: ... */
-
-    key=FIPS_rsa_new();
-    clen=setrsakey(key,expected_ctext);
-    /* ...1) apply public key to plaintext, resulting ciphertext must be
-     * different
-    */
-    i=RSA_public_encrypt(128,original_ptext,ctext,key,
-                        RSA_NO_PADDING);
-    if(i != clen || memcmp(ctext,expected_ctext,i))
-       {
-       FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
-       goto err;
-       }
-    if(!memcmp(ctext,original_ptext,i))
-       {
-       FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
-       goto err;
-       }
-    /* ...2) apply private key to ciphertext and compare result to
-     *       original plaintext; results must be equal
-    */
-    i=RSA_private_decrypt(i,ctext,ptext,key,RSA_NO_PADDING);
-    if(i != 128 || memcmp(ptext,original_ptext,i))
        {
-       FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
-       goto err;
-       }
+       int ret = 0;
+       RSA *key = NULL;
+       EVP_PKEY pk;
+       key=FIPS_rsa_new();
+       setrsakey(key);
+       pk.type = EVP_PKEY_RSA;
+       pk.pkey.rsa = key;
 
-    /* Perform sign and verify Known Answer Test by... */
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_SHA1, sizeof(kat_RSA_SHA1),
+                               EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                               "RSA SHA1 PKCS#1"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_SHA224, sizeof(kat_RSA_SHA224),
+                               EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                               "RSA SHA224 PKCS#1"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_SHA256, sizeof(kat_RSA_SHA256),
+                               EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                               "RSA SHA256 PKCS#1"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_SHA384, sizeof(kat_RSA_SHA384),
+                               EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                               "RSA SHA384 PKCS#1"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_SHA512, sizeof(kat_RSA_SHA512),
+                               EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+                               "RSA SHA512 PKCS#1"))
+               goto err;
 
-    /* ...1)  using the same RSA key to encrypt the SHA-1 hash of a
-     * plaintext value larger than the RSA key size
-    */
-    if (RSA_size(key) >= sizeof(original_ptext) - 1)
-       {
-       FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
-       goto err;
-       }
-    /* ...2) then generate the SHA-1 digest of plaintext, and compare the
-     * digest to the Known Answer (note here we duplicate the SHA-1 KAT)
-     */
-    SHA1(original_ptext,sizeof(original_ptext) - 1,md);
-    if(memcmp(md,mdkat,SHA_DIGEST_LENGTH))
-       {
-       FIPSerr(FIPS_F_FIPS_SELFTEST_SHA,FIPS_R_SELFTEST_FAILED);
-       goto err;
-       }
-    /* ...3) then encrypt the digest, and compare the ciphertext
-     * to the Known Answer
-     */
-    i=RSA_private_encrypt(sizeof(md),md,ctext,key,RSA_PKCS1_PADDING);
-    if(i != clen || memcmp(ctextkat,ctext,i))
-       {
-       FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
-       goto err;
-       }
-    /* ...4) and finally decrypt the signed digest and compare with
-     * the original Known Answer
-     */
-    i=RSA_public_decrypt(i,ctext,md,key,RSA_PKCS1_PADDING);
-    if(i != sizeof(md) || memcmp(mdkat,md,i))
-       {
-       FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
-       goto err;
-       }
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1),
+                               EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS,
+                               "RSA SHA1 PSS"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224),
+                               EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PSS,
+                               "RSA SHA224 PSS"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256),
+                               EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PSS,
+                               "RSA SHA256 PSS"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384),
+                               EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PSS,
+                               "RSA SHA384 PSS"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                               kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512),
+                               EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PSS,
+                               "RSA SHA512 PSS"))
+               goto err;
 
-    ret = 1;
 
-    err:
-    FIPS_rsa_free(key);
-    return ret;
-    }
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                       kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1),
+                       EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931,
+                       "RSA SHA1 X931"))
+               goto err;
+       /* NB: SHA224 not supported in X9.31 */
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                       kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256),
+                       EVP_sha256(), EVP_MD_CTX_FLAG_PAD_X931,
+                       "RSA SHA256 X931"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                       kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384),
+                       EVP_sha384(), EVP_MD_CTX_FLAG_PAD_X931,
+                       "RSA SHA384 X931"))
+               goto err;
+       if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+                       kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512),
+                       EVP_sha512(), EVP_MD_CTX_FLAG_PAD_X931,
+                       "RSA SHA512 X931"))
+               goto err;
+
+
+       ret = 1;
+
+       err:
+       FIPS_rsa_free(key);
+       return ret;
+       }
 
 #endif /* def OPENSSL_FIPS */
index 49d3b5c854b0f9de4722f93770b2ec3f2754e445..a90da2ebcf69b26f192e61435fb9ba9a68ef2f17 100644 (file)
@@ -151,8 +151,15 @@ static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
 
        if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
                {
+               int hash_id;
                memcpy(tmpdinfo, md, m_len);
-               tmpdinfo[m_len] = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
+               hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
+               if (hash_id == -1)
+                       {
+                       RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+                       return 0;
+                       }
+               tmpdinfo[m_len] = (unsigned char)hash_id;
                i = m_len + 1;
                rsa_pad_mode = RSA_X931_PADDING;
                }
@@ -164,7 +171,7 @@ static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
                if (!der)
                        {
                        RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
-                       return(0);
+                       return 0;
                        }
                memcpy(tmpdinfo, der, dlen);
                memcpy(tmpdinfo + dlen, md, m_len);
@@ -273,12 +280,19 @@ static int fips_rsa_verify(int dtype,
 
        if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
                {
+               int hash_id;
                if (i != (int)(diglen + 1))
                        {
                        RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
                        goto err;
                        }
-               if (s[diglen] != RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx)))
+               hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
+               if (hash_id == -1)
+                       {
+                       RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+                       goto err;
+                       }
+               if (s[diglen] != (unsigned char)hash_id)
                        {
                        RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
                        goto err;