aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/dsa
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2011-04-23 19:55:55 +0000
committerDr. Stephen Henson <steve@openssl.org>2011-04-23 19:55:55 +0000
commitcac4fb58e02d8cf799d75212179f56c69e652ec7 (patch)
treed96dd01b03818cc88755fee7fe19d28d3ed9b43e /crypto/dsa
parent9e5fe439b4e8fb4198f241f2ba16a029a480d5f5 (diff)
downloadopenssl-cac4fb58e02d8cf799d75212179f56c69e652ec7.tar.gz
Add PRNG security strength checking.
Diffstat (limited to 'crypto/dsa')
-rw-r--r--crypto/dsa/dsa.h1
-rw-r--r--crypto/dsa/dsa_gen.c68
-rw-r--r--crypto/dsa/dsa_key.c5
-rw-r--r--crypto/dsa/dsa_ossl.c5
4 files changed, 69 insertions, 10 deletions
diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h
index b68fbce169..86766dacb4 100644
--- a/crypto/dsa/dsa.h
+++ b/crypto/dsa/dsa.h
@@ -113,6 +113,7 @@
*/
#define DSA_FLAG_NON_FIPS_ALLOW 0x0400
+#define DSA_FLAG_FIPS_CHECKED 0x0800
#ifdef __cplusplus
extern "C" {
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)
{
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index 942000e3a5..3df9a6c6a9 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -106,11 +106,14 @@ static int dsa_builtin_keygen(DSA *dsa)
BIGNUM *pub_key=NULL,*priv_key=NULL;
#ifdef OPENSSL_FIPS
- if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
+ if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
+ && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
{
DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL);
goto err;
}
+ if (!fips_check_dsa_prng(dsa, 0, 0))
+ goto err;
#endif
if ((ctx=BN_CTX_new()) == NULL) goto err;
diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c
index f1512a40dd..acf7af95c4 100644
--- a/crypto/dsa/dsa_ossl.c
+++ b/crypto/dsa/dsa_ossl.c
@@ -150,11 +150,14 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
return NULL;
}
- if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
+ if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)
+ && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
{
DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL);
return NULL;
}
+ if (!fips_check_dsa_prng(dsa, 0, 0))
+ goto err;
#endif
BN_init(&m);