summaryrefslogtreecommitdiffstats
path: root/crypto/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/rsa')
-rw-r--r--crypto/rsa/rsa.h4
-rw-r--r--crypto/rsa/rsa_gen.c46
-rw-r--r--crypto/rsa/rsa_x931g.c5
3 files changed, 53 insertions, 2 deletions
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index b91501a8d0..7174f9cee8 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -470,6 +470,10 @@ RSA *RSAPrivateKey_dup(RSA *rsa);
*/
#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
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index 484468da05..24f9eaf4d6 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -74,8 +74,49 @@
#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
#include <openssl/evp.h>
+/* Check PRNG has sufficient security level to handle an RSA operation */
+
+int fips_check_rsa_prng(RSA *rsa, int bits)
+ {
+ int strength;
+ if (!FIPS_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)
{
const unsigned char tbs[] = "RSA Pairwise Check Data";
@@ -164,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_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();
diff --git a/crypto/rsa/rsa_x931g.c b/crypto/rsa/rsa_x931g.c
index 1ccd0a1969..819a728954 100644
--- a/crypto/rsa/rsa_x931g.c
+++ b/crypto/rsa/rsa_x931g.c
@@ -210,7 +210,8 @@ int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb)
BN_CTX *ctx = NULL;
#ifdef OPENSSL_FIPS
- if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)
+ if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) &&
+ (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
{
FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT);
return 0;
@@ -227,6 +228,8 @@ int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb)
FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED);
return 0;
}
+ if (!fips_check_rsa_prng(rsa, bits))
+ return 0;
#endif
ctx = BN_CTX_new();