Commit 357d5de5 authored by Nils Larsch's avatar Nils Larsch
Browse files

add support for DSA with SHA2

parent 0501f02b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@

 Changes between 0.9.8e and 0.9.9  [xx XXX xxxx]

  *) Add support for dsa-with-SHA224 and dsa-with-SHA256.
     Use the leftmost N bytes of the signature input if the input is
     larger than the prime q (with N being the size in bytes of q).
     [Nils Larsch]

  *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses
     it yet and it is largely untested.
     [Steve Henson]
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ LIBOBJ= dsa_gen.o dsa_key.o dsa_lib.o dsa_asn1.o dsa_vrf.o dsa_sign.o \
SRC= $(LIBSRC)

EXHEADER= dsa.h
HEADER=	$(EXHEADER)
HEADER=	dsa_locl.h $(EXHEADER)

ALL=    $(GENERAL) $(SRC) $(HEADER)

+2 −0
Original line number Diff line number Diff line
@@ -254,6 +254,8 @@ DH *DSA_dup_DH(const DSA *r);
				EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)

#define	EVP_PKEY_CTRL_DSA_PARAMGEN_BITS		(EVP_PKEY_ALG_CTRL + 1)
#define	EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS	(EVP_PKEY_ALG_CTRL + 2)
#define	EVP_PKEY_CTRL_DSA_PARAMGEN_MD		(EVP_PKEY_ALG_CTRL + 3)

/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
+9 −4
Original line number Diff line number Diff line
@@ -537,12 +537,17 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
		case ASN1_PKEY_CTRL_PKCS7_SIGN:
		if (arg1 == 0)
			{
			int snid, hnid;
			X509_ALGOR *alg1, *alg2;
			PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
			X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_sha1),
							V_ASN1_NULL, 0);
			X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_dsaWithSHA1),
							V_ASN1_UNDEF, 0);
			if (alg1 == NULL || alg1->algorithm == NULL)
				return -1;
			hnid = OBJ_obj2nid(alg1->algorithm);
			if (hnid == NID_undef)
				return -1;
			if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
				return -1; 
			X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
			}
		return 1;

+72 −43
Original line number Diff line number Diff line
@@ -74,17 +74,12 @@
#ifndef OPENSSL_NO_SHA

#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/rand.h>
#include <openssl/sha.h>

static int dsa_builtin_paramgen(DSA *ret, int bits,
		unsigned char *seed_in, int seed_len,
		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
#include "dsa_locl.h"

int DSA_generate_parameters_ex(DSA *ret, int bits,
		unsigned char *seed_in, int seed_len,
@@ -93,41 +88,72 @@ int DSA_generate_parameters_ex(DSA *ret, int bits,
	if(ret->meth->dsa_paramgen)
		return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
				counter_ret, h_ret, cb);
	return dsa_builtin_paramgen(ret, bits, seed_in, seed_len,
			counter_ret, h_ret, cb);
	else
		{
		const EVP_MD *evpmd;
		size_t qbits = bits >= 2048 ? 256 : 160;

		if (bits >= 2048)
			{
			qbits = 256;
			evpmd = EVP_sha256();
			}
		else
			{
			qbits = 160;
			evpmd = EVP_sha1();
			}

static int dsa_builtin_paramgen(DSA *ret, int bits,
		unsigned char *seed_in, int seed_len,
		return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
				seed_in, seed_len, counter_ret, h_ret, cb);
		}
	}

int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
	const EVP_MD *evpmd, unsigned char *seed_in, size_t seed_len,
	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
	{
	int ok=0;
	unsigned char seed[SHA_DIGEST_LENGTH];
	unsigned char md[SHA_DIGEST_LENGTH];
	unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
	unsigned char seed[SHA256_DIGEST_LENGTH];
	unsigned char md[SHA256_DIGEST_LENGTH];
	unsigned char buf[SHA256_DIGEST_LENGTH],buf2[SHA256_DIGEST_LENGTH];
	BIGNUM *r0,*W,*X,*c,*test;
	BIGNUM *g=NULL,*q=NULL,*p=NULL;
	BN_MONT_CTX *mont=NULL;
	int k,n=0,i,b,m=0;
	size_t i;
	int k,n=0,b,m=0, qsize = qbits >> 3;
	int counter=0;
	int r=0;
	BN_CTX *ctx=NULL;
	unsigned int h=2;

	if (bits < 512) bits=512;
	if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
	    qsize != SHA256_DIGEST_LENGTH)
		/* invalid q size */
		return 0;

	if (evpmd == NULL)
		/* use SHA1 as default */
		evpmd = EVP_sha1();

	if (bits < 512)
		bits = 512;

	bits = (bits+63)/64*64;

	if (seed_len < 20)
	if (seed_len < qsize)
		seed_in = NULL;		/* seed buffer too small -- ignore */
	if (seed_len > 20) 
		seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
	if (seed_len > qsize) 
		seed_len = qsize;	/* App. 2.2 of FIPS PUB 186 allows larger SEED,
					 * but our internal buffers are restricted to 160 bits*/
	if ((seed_in != NULL) && (seed_len == 20))
	if (seed_in != NULL)
		memcpy(seed, seed_in, seed_len);

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

	if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
	if ((mont=BN_MONT_CTX_new()) == NULL)
		goto err;

	BN_CTX_start(ctx);
	r0 = BN_CTX_get(ctx);
@@ -154,7 +180,7 @@ static int dsa_builtin_paramgen(DSA *ret, int bits,

			if (!seed_len)
				{
				RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH);
				RAND_pseudo_bytes(seed, qsize);
				seed_is_random = 1;
				}
			else
@@ -162,25 +188,27 @@ static int dsa_builtin_paramgen(DSA *ret, int bits,
				seed_is_random = 0;
				seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
				}
			memcpy(buf,seed,SHA_DIGEST_LENGTH);
			memcpy(buf2,seed,SHA_DIGEST_LENGTH);
			memcpy(buf , seed, qsize);
			memcpy(buf2, seed, qsize);
			/* precompute "SEED + 1" for step 7: */
			for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
			for (i = qsize-1; i >= 0; i--)
				{
				buf[i]++;
				if (buf[i] != 0) break;
				if (buf[i] != 0)
					break;
				}

			/* step 2 */
			EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
			EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL);
			for (i=0; i<SHA_DIGEST_LENGTH; i++)
			EVP_Digest(seed, qsize, md,   NULL, evpmd, NULL);
			EVP_Digest(buf,  qsize, buf2, NULL, evpmd, NULL);
			for (i = 0; i < qsize; i++)
				md[i]^=buf2[i];

			/* step 3 */
			md[0] |= 0x80;
			md[SHA_DIGEST_LENGTH-1]|=0x01;
			if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;
			md[qsize-1] |= 0x01;
			if (!BN_bin2bn(md, qsize, q))
				goto err;

			/* step 4 */
			r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
@@ -215,18 +243,19 @@ static int dsa_builtin_paramgen(DSA *ret, int bits,
			for (k=0; k<=n; k++)
				{
				/* obtain "SEED + offset + k" by incrementing: */
				for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
				for (i = qsize-1; i >= 0; i--)
					{
					buf[i]++;
					if (buf[i] != 0) break;
					if (buf[i] != 0)
						break;
					}

				EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
				EVP_Digest(buf, qsize, md ,NULL, evpmd, NULL);

				/* step 8 */
				if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0))
				if (!BN_bin2bn(md, qsize, r0))
					goto err;
				if (!BN_lshift(r0,r0,160*k)) goto err;
				if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err;
				if (!BN_add(W,W,r0)) goto err;
				}

@@ -300,7 +329,7 @@ err:
			ok=0;
			goto err;
			}
		if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20);
		if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed, qsize);
		if (counter_ret != NULL) *counter_ret=counter;
		if (h_ret != NULL) *h_ret=h;
		}
Loading