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

FIPS mode DSA changes:

Check for selftest failures.

Pairwise consistency test for RSA key generation.

Use some EVP macros instead of EVP functions.

Use minimal FIPS EVP where needed.

Key size restrictions.
parent c553721e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ top:
all:	lib

lib:	$(LIBOBJ)
	$(AR) $(LIB) $(LIBOBJ)
	$(ARX) $(LIB) $(LIBOBJ)
	$(RANLIB) $(LIB) || echo Never mind.
	@touch lib

+27 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@
# define OPENSSL_DSA_MAX_MODULUS_BITS	10000
#endif

#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024

#define DSA_FLAG_CACHE_MONT_P	0x01
#define DSA_FLAG_NO_EXP_CONSTTIME       0x02 /* new with 0.9.7h; the built-in DSA
                                              * implementation now uses constant time
@@ -97,6 +99,21 @@
                                              * be used for all exponents.
                                              */

/* If this flag is set the DSA method is FIPS compliant and can be used
 * in FIPS mode. This is set in the validated module method. If an
 * application sets this flag in its own methods it is its reposibility
 * to ensure the result is compliant.
 */

#define DSA_FLAG_FIPS_METHOD			0x0400

/* If this flag is set the operations normally disabled in FIPS mode are
 * permitted it is then the applications responsibility to ensure that the
 * usage is compliant.
 */

#define DSA_FLAG_NON_FIPS_ALLOW			0x0400

#ifdef  __cplusplus
extern "C" {
#endif
@@ -189,6 +206,13 @@ void DSA_set_default_method(const DSA_METHOD *);
const DSA_METHOD *DSA_get_default_method(void);
int	DSA_set_method(DSA *dsa, const DSA_METHOD *);

#ifdef OPENSSL_FIPS
DSA *	FIPS_dsa_new(void);
void	FIPS_dsa_free (DSA *r);
DSA_SIG * FIPS_dsa_sign_ctx(DSA *dsa, EVP_MD_CTX *ctx);
int FIPS_dsa_verify_ctx(DSA *dsa, EVP_MD_CTX *ctx, DSA_SIG *s);
#endif

DSA *	DSA_new(void);
DSA *	DSA_new_method(ENGINE *engine);
void	DSA_free (DSA *r);
@@ -270,6 +294,8 @@ void ERR_load_DSA_strings(void);
#define DSA_F_DO_DSA_PRINT				 104
#define DSA_F_DSAPARAMS_PRINT				 100
#define DSA_F_DSAPARAMS_PRINT_FP			 101
#define DSA_F_DSA_BUILTIN_KEYGEN			 124
#define DSA_F_DSA_BUILTIN_PARAMGEN			 125
#define DSA_F_DSA_DO_SIGN				 112
#define DSA_F_DSA_DO_VERIFY				 113
#define DSA_F_DSA_NEW_METHOD				 103
@@ -297,6 +323,7 @@ void ERR_load_DSA_strings(void);
#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
#define DSA_R_DECODE_ERROR				 104
#define DSA_R_INVALID_DIGEST_TYPE			 106
#define DSA_R_KEY_SIZE_TOO_SMALL			 111
#define DSA_R_MISSING_PARAMETERS			 101
#define DSA_R_MODULUS_TOO_LARGE				 103
#define DSA_R_NEED_NEW_SETUP_VALUES			 110
+3 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_FUNC(DSA_F_DO_DSA_PRINT),	"DO_DSA_PRINT"},
{ERR_FUNC(DSA_F_DSAPARAMS_PRINT),	"DSAparams_print"},
{ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP),	"DSAparams_print_fp"},
{ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN),	"DSA_BUILTIN_KEYGEN"},
{ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN),	"DSA_BUILTIN_PARAMGEN"},
{ERR_FUNC(DSA_F_DSA_DO_SIGN),	"DSA_do_sign"},
{ERR_FUNC(DSA_F_DSA_DO_VERIFY),	"DSA_do_verify"},
{ERR_FUNC(DSA_F_DSA_NEW_METHOD),	"DSA_new_method"},
@@ -104,6 +106,7 @@ static ERR_STRING_DATA DSA_str_reasons[]=
{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
{ERR_REASON(DSA_R_DECODE_ERROR)          ,"decode error"},
{ERR_REASON(DSA_R_INVALID_DIGEST_TYPE)   ,"invalid digest type"},
{ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL)    ,"key size too small"},
{ERR_REASON(DSA_R_MISSING_PARAMETERS)    ,"missing parameters"},
{ERR_REASON(DSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
{ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES) ,"need new setup values"},
+21 −0
Original line number Diff line number Diff line
@@ -73,12 +73,18 @@

#ifndef OPENSSL_NO_SHA

#define OPENSSL_FIPSEVP

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#endif

#include "dsa_locl.h"

int DSA_generate_parameters_ex(DSA *ret, int bits,
@@ -127,6 +133,21 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
	BN_CTX *ctx=NULL;
	unsigned int h=2;

#ifdef OPENSSL_FIPS
	if(FIPS_selftest_failed())
	    {
	    FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN,
		    FIPS_R_FIPS_SELFTEST_FAILED);
	    goto err;
	    }

	if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
		{
		DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL);
		goto err;
		}
#endif

	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
	    qsize != SHA256_DIGEST_LENGTH)
		/* invalid q size */
+45 −0
Original line number Diff line number Diff line
@@ -64,6 +64,37 @@
#include <openssl/dsa.h>
#include <openssl/rand.h>

#ifdef OPENSSL_FIPS

#include <openssl/fips.h>
#include <openssl/evp.h>

static int fips_dsa_pairwise_fail = 0;

void FIPS_corrupt_dsa_keygen(void)
	{
	fips_dsa_pairwise_fail = 1;
	}

static int fips_check_dsa(DSA *dsa)
	{
	EVP_PKEY pk;
	unsigned char tbs[] = "DSA Pairwise Check Data";
    	pk.type = EVP_PKEY_DSA;
    	pk.pkey.dsa = dsa;

	if (!fips_pkey_signature_test(&pk, tbs, -1,
					NULL, 0, EVP_sha1(), 0, NULL))
		{
		FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
		fips_set_selftest_fail();
		return 0;
		}
	return 1;
	}

#endif

static int dsa_builtin_keygen(DSA *dsa);

int DSA_generate_key(DSA *dsa)
@@ -79,6 +110,14 @@ static int dsa_builtin_keygen(DSA *dsa)
	BN_CTX *ctx=NULL;
	BIGNUM *pub_key=NULL,*priv_key=NULL;

#ifdef OPENSSL_FIPS
	if (FIPS_mode() && (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;
		}
#endif

	if ((ctx=BN_CTX_new()) == NULL) goto err;

	if (dsa->priv_key == NULL)
@@ -117,6 +156,12 @@ static int dsa_builtin_keygen(DSA *dsa)

	dsa->priv_key=priv_key;
	dsa->pub_key=pub_key;
#ifdef OPENSSL_FIPS
	if (fips_dsa_pairwise_fail)
		BN_add_word(dsa->pub_key, 1);
	if(!fips_check_dsa(dsa))
#endif
	    goto err;
	ok=1;

err:
Loading