Commit cac4fb58 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add PRNG security strength checking.

parent 9e5fe439
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4,6 +4,10 @@

 Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]

  *) Add PRNG security strength checks to RSA, DSA and ECDSA using 
     information in FIPS186-3, SP800-57 and SP800-131A.
     [Steve Henson]

  *) CCM support via EVP. Interface is very similar to GCM case except we
     must supply all data in one chunk (i.e. no update, final) and the
     message length must be supplied if AAD is used. Add algorithm test
+1 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@
 */

#define DSA_FLAG_NON_FIPS_ALLOW			0x0400
#define DSA_FLAG_FIPS_CHECKED			0x0800

#ifdef  __cplusplus
extern "C" {
+60 −8
Original line number Diff line number Diff line
@@ -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)
		{
+4 −1
Original line number Diff line number Diff line
@@ -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;
+4 −1
Original line number Diff line number Diff line
@@ -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);
Loading