diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2011-04-23 19:55:55 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2011-04-23 19:55:55 +0000 |
commit | cac4fb58e02d8cf799d75212179f56c69e652ec7 (patch) | |
tree | d96dd01b03818cc88755fee7fe19d28d3ed9b43e /crypto/dsa/dsa_gen.c | |
parent | 9e5fe439b4e8fb4198f241f2ba16a029a480d5f5 (diff) |
Add PRNG security strength checking.
Diffstat (limited to 'crypto/dsa/dsa_gen.c')
-rw-r--r-- | crypto/dsa/dsa_gen.c | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index 6517b1592d..4d6bbc0d05 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -83,6 +83,7 @@ #include <openssl/sha.h> #ifdef OPENSSL_FIPS #include <openssl/fips.h> +#include <openssl/fips_rand.h> #endif #include "dsa_locl.h" @@ -140,7 +141,8 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, goto err; } - if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + if (FIPS_mode() && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW) + && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL); goto err; @@ -375,7 +377,24 @@ err: */ -static int dsa2_security_strength(size_t L, size_t N) +static int fips_ffc_strength(size_t L, size_t N) + { + if (L >= 15360 && N >= 512) + return 256; + if (L >= 7680 && N >= 384) + return 192; + if (L >= 3072 && N >= 256) + return 128; + if (L >= 2048 && N >= 224) + return 112; + if (L >= 1024 && N >= 160) + return 80; + return 0; + } + +/* Valid DSA2 parameters from FIPS 186-3 */ + +static int dsa2_valid_parameters(size_t L, size_t N) { if (L == 1024 && N == 160) return 80; @@ -388,6 +407,42 @@ static int dsa2_security_strength(size_t L, size_t N) return 0; } +int fips_check_dsa_prng(DSA *dsa, size_t L, size_t N) + { + int strength; + if (!FIPS_mode()) + return 1; + + if (dsa->flags & (DSA_FLAG_NON_FIPS_ALLOW|DSA_FLAG_FIPS_CHECKED)) + return 1; + + if (!L || !N) + { + L = BN_num_bits(dsa->p); + N = BN_num_bits(dsa->q); + } + if (!dsa2_valid_parameters(L, N)) + { + FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG, FIPS_R_INVALID_PARAMETERS); + return 0; + } + + strength = fips_ffc_strength(L, N); + + if (!strength) + { + FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG,FIPS_R_KEY_TOO_SHORT); + return 0; + } + + if (FIPS_rand_strength() >= strength) + return 1; + + FIPSerr(FIPS_F_FIPS_CHECK_DSA_PRNG,FIPS_R_PRNG_STRENGTH_TOO_LOW); + return 0; + + } + /* This is a parameter generation algorithm for the DSA2 algorithm as * described in FIPS 186-3. */ @@ -417,13 +472,10 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, FIPS_R_FIPS_SELFTEST_FAILED); goto err; } -#endif - if (!dsa2_security_strength(L, N)) - { - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); - ok = 0; + + if (!fips_check_dsa_prng(ret, L, N)) goto err; - } +#endif if (evpmd == NULL) { |