diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2014-04-23 09:56:37 +0200 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2014-04-23 09:56:37 +0200 | 
| commit | e436c963f0976b885a7db04681344779e26dd3b5 (patch) | |
| tree | 240663106f32e02e1c34080656f4ef21a2e1776e /main/openssl/crypto/dsa | |
| parent | 6a99715a9b072fa249e79c98cd9f03991f0f1219 (diff) | |
Update OpenSSL to 1.0.1g and statically link OpenVPN with it
Diffstat (limited to 'main/openssl/crypto/dsa')
| -rw-r--r-- | main/openssl/crypto/dsa/dsa.h | 30 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_ameth.c | 47 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_asn1.c | 40 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_err.c | 8 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_gen.c | 35 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_key.c | 16 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_lib.c | 22 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_locl.h | 1 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_ossl.c | 44 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_pmeth.c | 6 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_sign.c | 57 | ||||
| -rw-r--r-- | main/openssl/crypto/dsa/dsa_vrf.c | 29 | 
12 files changed, 283 insertions, 52 deletions
diff --git a/main/openssl/crypto/dsa/dsa.h b/main/openssl/crypto/dsa/dsa.h index ac50a5c8..7531c653 100644 --- a/main/openssl/crypto/dsa/dsa.h +++ b/main/openssl/crypto/dsa/dsa.h @@ -96,6 +96,25 @@                                                * faster variable sliding window method to                                                * be used for all exponents.                                                */ +#define DSA_FLAG_NONCE_FROM_HASH	0x04 /* Causes the DSA nonce to be calculated +						from SHA512(private_key + H(message) + +						random). This strengthens DSA against a +						weak PRNG. */ + +/* 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" { @@ -115,8 +134,9 @@ struct dsa_method  	{  	const char *name;  	DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa); -	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, -								BIGNUM **rp); +	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, +			      BIGNUM **kinvp, BIGNUM **rp, +			      const unsigned char *dgst, int dlen);  	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,  			     DSA_SIG *sig, DSA *dsa);  	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, @@ -272,6 +292,8 @@ void ERR_load_DSA_strings(void);  #define DSA_F_DSAPARAMS_PRINT_FP			 101  #define DSA_F_DSA_DO_SIGN				 112  #define DSA_F_DSA_DO_VERIFY				 113 +#define DSA_F_DSA_GENERATE_KEY				 124 +#define DSA_F_DSA_GENERATE_PARAMETERS_EX		 123  #define DSA_F_DSA_NEW_METHOD				 103  #define DSA_F_DSA_PARAM_DECODE				 119  #define DSA_F_DSA_PRINT_FP				 105 @@ -282,6 +304,7 @@ void ERR_load_DSA_strings(void);  #define DSA_F_DSA_SIGN					 106  #define DSA_F_DSA_SIGN_SETUP				 107  #define DSA_F_DSA_SIG_NEW				 109 +#define DSA_F_DSA_SIG_PRINT				 125  #define DSA_F_DSA_VERIFY				 108  #define DSA_F_I2D_DSA_SIG				 111  #define DSA_F_OLD_DSA_PRIV_DECODE			 122 @@ -298,6 +321,9 @@ void ERR_load_DSA_strings(void);  #define DSA_R_INVALID_DIGEST_TYPE			 106  #define DSA_R_MISSING_PARAMETERS			 101  #define DSA_R_MODULUS_TOO_LARGE				 103 +#define DSA_R_NEED_NEW_SETUP_VALUES			 110 +#define DSA_R_NONCE_CANNOT_BE_PRECOMPUTED		 112 +#define DSA_R_NON_FIPS_DSA_METHOD			 111  #define DSA_R_NO_PARAMETERS_SET				 107  #define DSA_R_PARAMETER_ENCODING_ERROR			 105 diff --git a/main/openssl/crypto/dsa/dsa_ameth.c b/main/openssl/crypto/dsa/dsa_ameth.c index 6413aae4..376156ec 100644 --- a/main/openssl/crypto/dsa/dsa_ameth.c +++ b/main/openssl/crypto/dsa/dsa_ameth.c @@ -542,6 +542,52 @@ static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)  	return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);  	} +static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, +					const ASN1_STRING *sig, +					int indent, ASN1_PCTX *pctx) +	{ +	DSA_SIG *dsa_sig; +	const unsigned char *p; +	if (!sig) +		{ +		if (BIO_puts(bp, "\n") <= 0) +			return 0; +		else +			return 1; +		} +	p = sig->data; +	dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); +	if (dsa_sig) +		{ +		int rv = 0; +		size_t buf_len = 0; +		unsigned char *m=NULL; +		update_buflen(dsa_sig->r, &buf_len); +		update_buflen(dsa_sig->s, &buf_len); +		m = OPENSSL_malloc(buf_len+10); +		if (m == NULL) +			{ +			DSAerr(DSA_F_DSA_SIG_PRINT,ERR_R_MALLOC_FAILURE); +			goto err; +			} + +		if (BIO_write(bp, "\n", 1) != 1) +			goto err; + +		if (!ASN1_bn_print(bp,"r:   ",dsa_sig->r,m,indent)) +			goto err; +		if (!ASN1_bn_print(bp,"s:   ",dsa_sig->s,m,indent)) +			goto err; +		rv = 1; +		err: +		if (m) +			OPENSSL_free(m); +		DSA_SIG_free(dsa_sig); +		return rv; +		} +	return X509_signature_dump(bp, sig, indent); +	} +  static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)  	{  	switch (op) @@ -647,6 +693,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =  		dsa_copy_parameters,  		dsa_cmp_parameters,  		dsa_param_print, +		dsa_sig_print,  		int_dsa_free,  		dsa_pkey_ctrl, diff --git a/main/openssl/crypto/dsa/dsa_asn1.c b/main/openssl/crypto/dsa/dsa_asn1.c index c37460b2..60585343 100644 --- a/main/openssl/crypto/dsa/dsa_asn1.c +++ b/main/openssl/crypto/dsa/dsa_asn1.c @@ -61,6 +61,7 @@  #include <openssl/dsa.h>  #include <openssl/asn1.h>  #include <openssl/asn1t.h> +#include <openssl/rand.h>  /* Override the default new methods */  static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -87,7 +88,7 @@ ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = {  	ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)  } ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG) -IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG)  /* Override the default free and new methods */  static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -148,3 +149,40 @@ DSA *DSAparams_dup(DSA *dsa)  	{  	return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);  	} + +int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, +	     unsigned int *siglen, DSA *dsa) +	{ +	DSA_SIG *s; +	RAND_seed(dgst, dlen); +	s=DSA_do_sign(dgst,dlen,dsa); +	if (s == NULL) +		{ +		*siglen=0; +		return(0); +		} +	*siglen=i2d_DSA_SIG(s,&sig); +	DSA_SIG_free(s); +	return(1); +	} + +/* data has already been hashed (probably with SHA or SHA-1). */ +/* returns + *      1: correct signature + *      0: incorrect signature + *     -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, +	     const unsigned char *sigbuf, int siglen, DSA *dsa) +	{ +	DSA_SIG *s; +	int ret=-1; + +	s = DSA_SIG_new(); +	if (s == NULL) return(ret); +	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; +	ret=DSA_do_verify(dgst,dgst_len,s,dsa); +err: +	DSA_SIG_free(s); +	return(ret); +	} diff --git a/main/openssl/crypto/dsa/dsa_err.c b/main/openssl/crypto/dsa/dsa_err.c index bba984e9..e6171cce 100644 --- a/main/openssl/crypto/dsa/dsa_err.c +++ b/main/openssl/crypto/dsa/dsa_err.c @@ -1,6 +1,6 @@  /* crypto/dsa/dsa_err.c */  /* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved. + * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.   *   * Redistribution and use in source and binary forms, with or without   * modification, are permitted provided that the following conditions @@ -76,6 +76,8 @@ static ERR_STRING_DATA DSA_str_functs[]=  {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP),	"DSAparams_print_fp"},  {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_GENERATE_KEY),	"DSA_generate_key"}, +{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX),	"DSA_generate_parameters_ex"},  {ERR_FUNC(DSA_F_DSA_NEW_METHOD),	"DSA_new_method"},  {ERR_FUNC(DSA_F_DSA_PARAM_DECODE),	"DSA_PARAM_DECODE"},  {ERR_FUNC(DSA_F_DSA_PRINT_FP),	"DSA_print_fp"}, @@ -86,6 +88,7 @@ static ERR_STRING_DATA DSA_str_functs[]=  {ERR_FUNC(DSA_F_DSA_SIGN),	"DSA_sign"},  {ERR_FUNC(DSA_F_DSA_SIGN_SETUP),	"DSA_sign_setup"},  {ERR_FUNC(DSA_F_DSA_SIG_NEW),	"DSA_SIG_new"}, +{ERR_FUNC(DSA_F_DSA_SIG_PRINT),	"DSA_SIG_PRINT"},  {ERR_FUNC(DSA_F_DSA_VERIFY),	"DSA_verify"},  {ERR_FUNC(DSA_F_I2D_DSA_SIG),	"i2d_DSA_SIG"},  {ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE),	"OLD_DSA_PRIV_DECODE"}, @@ -105,6 +108,9 @@ static ERR_STRING_DATA DSA_str_reasons[]=  {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE)   ,"invalid digest type"},  {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"}, +{ERR_REASON(DSA_R_NONCE_CANNOT_BE_PRECOMPUTED),"nonce cannot be precomputed"}, +{ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD)   ,"non fips dsa method"},  {ERR_REASON(DSA_R_NO_PARAMETERS_SET)     ,"no parameters set"},  {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},  {0,NULL} diff --git a/main/openssl/crypto/dsa/dsa_gen.c b/main/openssl/crypto/dsa/dsa_gen.c index cb0b4538..c398761d 100644 --- a/main/openssl/crypto/dsa/dsa_gen.c +++ b/main/openssl/crypto/dsa/dsa_gen.c @@ -81,13 +81,33 @@  #include <openssl/sha.h>  #include "dsa_locl.h" +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +  int DSA_generate_parameters_ex(DSA *ret, int bits,  		const unsigned char *seed_in, int seed_len,  		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)  	{ +#ifdef OPENSSL_FIPS +	if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD) +			&& !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) +		{ +		DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD); +		return 0; +		} +#endif  	if(ret->meth->dsa_paramgen)  		return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,  				counter_ret, h_ret, cb); +#ifdef OPENSSL_FIPS +	else if (FIPS_mode()) +		{ +		return FIPS_dsa_generate_parameters_ex(ret, bits,  +							seed_in, seed_len, +							counter_ret, h_ret, cb); +		} +#endif  	else  		{  		const EVP_MD *evpmd; @@ -105,12 +125,13 @@ int DSA_generate_parameters_ex(DSA *ret, int bits,  			}  		return dsa_builtin_paramgen(ret, bits, qbits, evpmd, -				seed_in, seed_len, counter_ret, h_ret, cb); +			seed_in, seed_len, NULL, counter_ret, h_ret, cb);  		}  	}  int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,  	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, +	unsigned char *seed_out,  	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)  	{  	int ok=0; @@ -201,8 +222,10 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,  				}  			/* step 2 */ -			EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL); -			EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL); +			if (!EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL)) +				goto err; +			if (!EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL)) +				goto err;  			for (i = 0; i < qsize; i++)  				md[i]^=buf2[i]; @@ -251,7 +274,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,  						break;  					} -				EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL); +				if (!EVP_Digest(buf, qsize, md ,NULL, evpmd, +									NULL)) +					goto err;  				/* step 8 */  				if (!BN_bin2bn(md, qsize, r0)) @@ -332,6 +357,8 @@ err:  			}  		if (counter_ret != NULL) *counter_ret=counter;  		if (h_ret != NULL) *h_ret=h; +		if (seed_out) +			memcpy(seed_out, seed, qsize);  		}  	if(ctx)  		{ diff --git a/main/openssl/crypto/dsa/dsa_key.c b/main/openssl/crypto/dsa/dsa_key.c index c4aa86bc..9cf669b9 100644 --- a/main/openssl/crypto/dsa/dsa_key.c +++ b/main/openssl/crypto/dsa/dsa_key.c @@ -64,12 +64,28 @@  #include <openssl/dsa.h>  #include <openssl/rand.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +  static int dsa_builtin_keygen(DSA *dsa);  int DSA_generate_key(DSA *dsa)  	{ +#ifdef OPENSSL_FIPS +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) +		{ +		DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD); +		return 0; +		} +#endif  	if(dsa->meth->dsa_keygen)  		return dsa->meth->dsa_keygen(dsa); +#ifdef OPENSSL_FIPS +	if (FIPS_mode()) +		return FIPS_dsa_generate_key(dsa); +#endif  	return dsa_builtin_keygen(dsa);  	} diff --git a/main/openssl/crypto/dsa/dsa_lib.c b/main/openssl/crypto/dsa/dsa_lib.c index e9b75902..96d8d0c4 100644 --- a/main/openssl/crypto/dsa/dsa_lib.c +++ b/main/openssl/crypto/dsa/dsa_lib.c @@ -70,6 +70,10 @@  #include <openssl/dh.h>  #endif +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif +  const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;  static const DSA_METHOD *default_DSA_method = NULL; @@ -82,7 +86,16 @@ void DSA_set_default_method(const DSA_METHOD *meth)  const DSA_METHOD *DSA_get_default_method(void)  	{  	if(!default_DSA_method) +		{ +#ifdef OPENSSL_FIPS +		if (FIPS_mode()) +			return FIPS_dsa_openssl(); +		else +			return DSA_OpenSSL(); +#else  		default_DSA_method = DSA_OpenSSL(); +#endif +		}  	return default_DSA_method;  	} @@ -163,7 +176,7 @@ DSA *DSA_new_method(ENGINE *engine)  	ret->method_mont_p=NULL;  	ret->references=1; -	ret->flags=ret->meth->flags; +	ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;  	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);  	if ((ret->meth->init != NULL) && !ret->meth->init(ret))  		{ @@ -276,7 +289,8 @@ void *DSA_get_ex_data(DSA *d, int idx)  DH *DSA_dup_DH(const DSA *r)  	{  	/* DSA has p, q, g, optional pub_key, optional priv_key. -	 * DH has p, optional length, g, optional pub_key, optional priv_key. +	 * DH has p, optional length, g, optional pub_key, optional priv_key, +	 * optional q.  	 */   	DH *ret = NULL; @@ -290,7 +304,11 @@ DH *DSA_dup_DH(const DSA *r)  		if ((ret->p = BN_dup(r->p)) == NULL)  			goto err;  	if (r->q != NULL) +		{  		ret->length = BN_num_bits(r->q); +		if ((ret->q = BN_dup(r->q)) == NULL) +			goto err; +		}  	if (r->g != NULL)  		if ((ret->g = BN_dup(r->g)) == NULL)  			goto err; diff --git a/main/openssl/crypto/dsa/dsa_locl.h b/main/openssl/crypto/dsa/dsa_locl.h index 2b8cfee3..21e2e452 100644 --- a/main/openssl/crypto/dsa/dsa_locl.h +++ b/main/openssl/crypto/dsa/dsa_locl.h @@ -56,4 +56,5 @@  int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,  	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, +	unsigned char *seed_out,  	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); diff --git a/main/openssl/crypto/dsa/dsa_ossl.c b/main/openssl/crypto/dsa/dsa_ossl.c index a3ddd7d2..177fc545 100644 --- a/main/openssl/crypto/dsa/dsa_ossl.c +++ b/main/openssl/crypto/dsa/dsa_ossl.c @@ -67,7 +67,9 @@  #include <openssl/asn1.h>  static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); -static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, +			  BIGNUM **kinvp, BIGNUM **rp, +			  const unsigned char *dgst, int dlen);  static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,  			 DSA *dsa);  static int dsa_init(DSA *dsa); @@ -136,6 +138,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)  	BN_CTX *ctx=NULL;  	int reason=ERR_R_BN_LIB;  	DSA_SIG *ret=NULL; +	int noredo = 0;  	BN_init(&m);  	BN_init(&xr); @@ -150,10 +153,11 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)  	if (s == NULL) goto err;  	ctx=BN_CTX_new();  	if (ctx == NULL) goto err; - +redo:  	if ((dsa->kinv == NULL) || (dsa->r == NULL))  		{ -		if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err; +		if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r,dgst,dlen)) +			goto err;  		}  	else  		{ @@ -161,6 +165,7 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)  		dsa->kinv=NULL;  		r=dsa->r;  		dsa->r=NULL; +		noredo = 1;  		} @@ -181,6 +186,18 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)  	ret=DSA_SIG_new();  	if (ret == NULL) goto err; +	/* Redo if r or s is zero as required by FIPS 186-3: this is +	 * very unlikely. +	 */ +	if (BN_is_zero(r) || BN_is_zero(s)) +		{ +		if (noredo) +			{ +			reason = DSA_R_NEED_NEW_SETUP_VALUES; +			goto err; +			} +		goto redo; +		}  	ret->r = r;  	ret->s = s; @@ -199,7 +216,9 @@ err:  	return(ret);  	} -static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, +			  BIGNUM **kinvp, BIGNUM **rp, +			  const unsigned char *dgst, int dlen)  	{  	BN_CTX *ctx;  	BIGNUM k,kq,*K,*kinv=NULL,*r=NULL; @@ -225,8 +244,21 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)  	/* Get random k */  	do -		if (!BN_rand_range(&k, dsa->q)) goto err; -	while (BN_is_zero(&k)); +		{ +#ifndef OPENSSL_NO_SHA512 +		if (dsa->flags & DSA_FLAG_NONCE_FROM_HASH) +			{ +			/* If DSA_FLAG_NONCE_FROM_HASH is set then we calculate k from +			 * SHA512(private_key + H(message) + random). This protects the +			 * private key from a weak PRNG. */ +			if (!BN_generate_dsa_nonce(&k, dsa->q, dsa->priv_key, dgst, +						   dlen, ctx)) +				goto err; +			} +		else +#endif +			if (!BN_rand_range(&k, dsa->q)) goto err; +		} while (BN_is_zero(&k));  	if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)  		{  		BN_set_flags(&k, BN_FLG_CONSTTIME); diff --git a/main/openssl/crypto/dsa/dsa_pmeth.c b/main/openssl/crypto/dsa/dsa_pmeth.c index e2df54fe..715d8d67 100644 --- a/main/openssl/crypto/dsa/dsa_pmeth.c +++ b/main/openssl/crypto/dsa/dsa_pmeth.c @@ -189,7 +189,9 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)  		    EVP_MD_type((const EVP_MD *)p2) != NID_dsa    &&  		    EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA    &&  		    EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && -		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256) +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && +		    EVP_MD_type((const EVP_MD *)p2) != NID_sha512)  			{  			DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);  			return 0; @@ -253,7 +255,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)  	if (!dsa)  		return 0;  	ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, -	                           NULL, 0, NULL, NULL, pcb); +	                           NULL, 0, NULL, NULL, NULL, pcb);  	if (ret)  		EVP_PKEY_assign_DSA(pkey, dsa);  	else diff --git a/main/openssl/crypto/dsa/dsa_sign.c b/main/openssl/crypto/dsa/dsa_sign.c index 17555e58..8ace300a 100644 --- a/main/openssl/crypto/dsa/dsa_sign.c +++ b/main/openssl/crypto/dsa/dsa_sign.c @@ -61,30 +61,61 @@  #include "cryptlib.h"  #include <openssl/dsa.h>  #include <openssl/rand.h> +#include <openssl/bn.h>  DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)  	{ +#ifdef OPENSSL_FIPS +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) +		{ +		DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD); +		return NULL; +		} +#endif  	return dsa->meth->dsa_do_sign(dgst, dlen, dsa);  	} -int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, -	     unsigned int *siglen, DSA *dsa) +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)  	{ -	DSA_SIG *s; -	RAND_seed(dgst, dlen); -	s=DSA_do_sign(dgst,dlen,dsa); -	if (s == NULL) +#ifdef OPENSSL_FIPS +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))  		{ -		*siglen=0; -		return(0); +		DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD); +		return 0;  		} -	*siglen=i2d_DSA_SIG(s,&sig); -	DSA_SIG_free(s); -	return(1); +#endif +	if (dsa->flags & DSA_FLAG_NONCE_FROM_HASH) +		{ +		/* You cannot precompute the DSA nonce if it is required to +		 * depend on the message. */ +		DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NONCE_CANNOT_BE_PRECOMPUTED); +		return 0; +		} +	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0);  	} -int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +DSA_SIG *DSA_SIG_new(void)  	{ -	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); +	DSA_SIG *sig; +	sig = OPENSSL_malloc(sizeof(DSA_SIG)); +	if (!sig) +		return NULL; +	sig->r = NULL; +	sig->s = NULL; +	return sig; +	} + +void DSA_SIG_free(DSA_SIG *sig) +	{ +	if (sig) +		{ +		if (sig->r) +			BN_free(sig->r); +		if (sig->s) +			BN_free(sig->s); +		OPENSSL_free(sig); +		}  	} diff --git a/main/openssl/crypto/dsa/dsa_vrf.c b/main/openssl/crypto/dsa/dsa_vrf.c index 226a75ff..674cb5fa 100644 --- a/main/openssl/crypto/dsa/dsa_vrf.c +++ b/main/openssl/crypto/dsa/dsa_vrf.c @@ -64,26 +64,13 @@  int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,  		  DSA *dsa)  	{ +#ifdef OPENSSL_FIPS +	if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) +			&& !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) +		{ +		DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD); +		return -1; +		} +#endif  	return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);  	} - -/* data has already been hashed (probably with SHA or SHA-1). */ -/* returns - *      1: correct signature - *      0: incorrect signature - *     -1: error - */ -int DSA_verify(int type, const unsigned char *dgst, int dgst_len, -	     const unsigned char *sigbuf, int siglen, DSA *dsa) -	{ -	DSA_SIG *s; -	int ret=-1; - -	s = DSA_SIG_new(); -	if (s == NULL) return(ret); -	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; -	ret=DSA_do_verify(dgst,dgst_len,s,dsa); -err: -	DSA_SIG_free(s); -	return(ret); -	}  | 
