diff options
Diffstat (limited to 'crypto/rsa')
-rw-r--r-- | crypto/rsa/rsa.h | 4 | ||||
-rw-r--r-- | crypto/rsa/rsa_gen.c | 46 | ||||
-rw-r--r-- | crypto/rsa/rsa_x931g.c | 5 |
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(); |