Rename FIPS_mode_set and FIPS_mode. Theses symbols will be defined in
[openssl.git] / crypto / rsa / rsa_gen.c
index b8676ad020dc6303dca33ae52aef5d8382c56daf..d28f8725cd06fb637cbf568d631f747de19866d9 100644 (file)
@@ -62,6 +62,8 @@
  * - Geoff
  */
 
+#define OPENSSL_FIPSAPI
+
 #include <stdio.h>
 #include <time.h>
 #include "cryptlib.h"
 
 #ifdef OPENSSL_FIPS
 
+
 #include <openssl/fips.h>
+#include <openssl/fips_rand.h>
 #include <openssl/evp.h>
 
-static int fips_rsa_pairwise_fail = 0;
+/* Check PRNG has sufficient security level to handle an RSA operation */
 
-void FIPS_corrupt_rsa_keygen(void)
+int fips_check_rsa_prng(RSA *rsa, int bits)
        {
-       fips_rsa_pairwise_fail = 1;
+       int strength;
+       if (!FIPS_module_mode())
+               return 1;
+
+       if (rsa->flags & (RSA_FLAG_NON_FIPS_ALLOW|RSA_FLAG_CHECKED))
+               return 1;
+
+       if (bits == 0)
+               bits = BN_num_bits(rsa->n);
+
+       /* Should never happen */
+       if (bits < 1024)
+               {
+               FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_KEY_TOO_SHORT);
+               return 0;
+               }
+       /* From SP800-57 */
+       if (bits < 2048)
+               strength = 80;
+       else if (bits < 3072)
+               strength = 112;
+       else if (bits < 7680)
+               strength = 128;
+       else if (bits < 15360)
+               strength = 192;
+       else 
+               strength = 256;
+
+       if (FIPS_rand_strength() >= strength)
+               return 1;
+
+       FIPSerr(FIPS_F_FIPS_CHECK_RSA_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW);
+       return 0;
        }
+       
 
 int fips_check_rsa(RSA *rsa)
        {
@@ -90,12 +127,12 @@ int fips_check_rsa(RSA *rsa)
        pk.pkey.rsa = rsa;
 
        /* Perform pairwise consistency signature test */
-       if (!fips_pkey_signature_test(&pk, tbs, -1,
-                       NULL, 0, EVP_sha1(), RSA_PKCS1_PADDING, NULL)
-               || !fips_pkey_signature_test(&pk, tbs, -1,
-                       NULL, 0, EVP_sha1(), RSA_X931_PADDING, NULL)
-               || !fips_pkey_signature_test(&pk, tbs, -1,
-                       NULL, 0, EVP_sha1(), RSA_PKCS1_PSS_PADDING, NULL))
+       if (!fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
+                       NULL, 0, NULL, RSA_PKCS1_PADDING, NULL)
+               || !fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
+                       NULL, 0, NULL, RSA_X931_PADDING, NULL)
+               || !fips_pkey_signature_test(FIPS_TEST_PAIRWISE, &pk, tbs, 0,
+                       NULL, 0, NULL, RSA_PKCS1_PSS_PADDING, NULL))
                goto err;
        /* Now perform pairwise consistency encrypt/decrypt test */
        ctbuf = OPENSSL_malloc(RSA_size(rsa));
@@ -168,11 +205,14 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
            return 0;
            }
 
-       if (FIPS_mode() && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+       if (FIPS_module_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) 
+               && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
            {
            FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT);
            return 0;
            }
+       if (!fips_check_rsa_prng(rsa, bits))
+           return 0;
 #endif
 
        ctx=BN_CTX_new();
@@ -287,9 +327,6 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
        if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
 
 #ifdef OPENSSL_FIPS
-       if (fips_rsa_pairwise_fail)
-               BN_add_word(rsa->n, 1);
-
        if(!fips_check_rsa(rsa))
            goto err;
 #endif