Commit e172d60d authored by Bodo Möller's avatar Bodo Möller
Browse files

Add ECDH support.

Additional changes:
 - use EC_GROUP_get_degree() in apps/req.c
 - add ECDSA and ECDH to apps/speed.c
 - adds support for EC curves over binary fields to ECDSA
 - new function EC_KEY_up_ref() in crypto/ec/ec_key.c
 - reorganize crypto/ecdsa/ecdsatest.c
 - add engine support for ECDH
 - fix a few bugs in ECDSA engine support

Submitted by: Douglas Stebila <douglas.stebila@sun.com>
parent f8fe7fa4
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -4,6 +4,12 @@

 Changes between 0.9.7 and 0.9.8  [xx XXX 2002]

  *) Add ECDH engine support.
     [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)]

  *) Add ECDH in new directory crypto/ecdh/.
     [Douglas Stebila (Sun Microsystems Laboratories)]

  *) Let BN_rand_range() abort with an error after 100 iterations
     without success (which indicates a broken PRNG).
     [Bodo Moeller]
@@ -214,7 +220,8 @@
     - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and
       d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make
       them suitable for ECDSA where domain parameters must be
       extracted before the specific public key.
       extracted before the specific public key;
     - ECDSA engine support has been added.
     [Nils Larsch <nla@trustcenter.de>]

  *) Include some named elliptic curves, and add OIDs from X9.62,
+14 −1
Original line number Diff line number Diff line
@@ -747,7 +747,20 @@ PROCESS_ARGS:
				$depflags .= "-DOPENSSL_NO_MDC2 ";
				$openssl_algorithm_defines .= "#define OPENSSL_NO_MDC2\n";
				}
			if ($algo eq "EC" || $algo eq "SHA" || $algo eq "SHA1")
			if ($algo eq "EC")
				{
				push @skip, "ecdsa";
				push @skip, "ecdh";
				$options .= " no-ecdsa";
				$options .= " no-ecdh";
				$flags .= "-DOPENSSL_NO_ECDSA ";
				$flags .= "-DOPENSSL_NO_ECDH ";
				$depflags .= "-DOPENSSL_NO_ECDSA ";
				$depflags .= "-DOPENSSL_NO_ECDH ";
				$openssl_algorithm_defines .= "#define OPENSSL_NO_ECDSA\n";
				$openssl_algorithm_defines .= "#define OPENSSL_NO_ECDH\n";
				}
			if ($algo eq "SHA" || $algo eq "SHA1")
				{
				push @skip, "ecdsa";
				$options .= " no-ecdsa";
+1 −1
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ SHLIBDIRS= crypto ssl
SDIRS=  \
	md2 md4 md5 sha mdc2 hmac ripemd \
	des rc2 rc4 rc5 idea bf cast \
	bn ec rsa dsa ecdsa dh dso engine aes \
	bn ec rsa dsa ecdsa dh ecdh dso engine aes \
	buffer bio stack lhash rand err objects \
	evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5

+1 −10
Original line number Diff line number Diff line
@@ -369,16 +369,7 @@ int MAIN(int argc, char **argv)
				BIO_free(in);
				in=NULL;
				
				{
				BIGNUM *order = BN_new();
				
				if (!order)
					goto end;
				if (!EC_GROUP_get_order(ec_params->group, order, NULL))
					goto end;
				newkey = BN_num_bits(order);
				BN_free(order);
				}
				newkey = EC_GROUP_get_degree(ec_params->group);

				}
			else
+635 −0
Original line number Diff line number Diff line
@@ -55,6 +55,32 @@
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by 
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the OpenSSL open source
 * license provided above.
 *
 * In addition, Sun covenants to all licensees who provide a reciprocal
 * covenant with respect to their own patents if any, not to sue under
 * current and future patent claims necessarily infringed by the making,
 * using, practicing, selling, offering for sale and/or otherwise
 * disposing of the Contribution as delivered hereunder 
 * (or portions thereof), provided that such covenant shall not apply:
 *  1) for code that a licensee deletes from the Contribution;
 *  2) separates from the Contribution; or
 *  3) for infringements caused by:
 *       i) the modification of the Contribution or
 *      ii) the combination of the Contribution with other software or
 *          devices where such combination causes the infringement.
 *
 * The ECDH and ECDSA speed test software is originally written by 
 * Sumit Gupta of Sun Microsystems Laboratories.
 *
 */

/* most of this code has been pilfered from my libdes speed.c program */

@@ -62,6 +88,8 @@
#define SECONDS		3	
#define RSA_SECONDS	10
#define DSA_SECONDS	10
#define ECDSA_SECONDS   10
#define ECDH_SECONDS    10

/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
@@ -184,6 +212,12 @@
#ifndef OPENSSL_NO_DSA
#include "./testdsa.h"
#endif
#ifndef OPENSSL_NO_ECDSA
#include <openssl/ecdsa.h>
#endif
#ifndef OPENSSL_NO_ECDH
#include <openssl/ecdh.h>
#endif

/* The following if from times(3) man page.  It may need to be changed */
#ifndef HZ
@@ -226,6 +260,10 @@ static int do_multi(int multi);
#define SIZE_NUM	5
#define RSA_NUM		4
#define DSA_NUM		3

#define EC_NUM       15
#define MAX_ECDH_SIZE 256

static const char *names[ALGOR_NUM]={
  "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
  "des cbc","des ede3","idea cbc",
@@ -235,6 +273,9 @@ static double results[ALGOR_NUM][SIZE_NUM];
static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
static double rsa_results[RSA_NUM][2];
static double dsa_results[DSA_NUM][2];
static double ecdsa_results[EC_NUM][2];
static double ecdh_results[EC_NUM][1];


#ifdef SIGALRM
#if defined(__STDC__) || defined(sgi) || defined(_AIX)
@@ -477,6 +518,23 @@ int MAIN(int argc, char **argv)
#define	R_RSA_1024	1
#define	R_RSA_2048	2
#define	R_RSA_4096	3

#define R_EC_P160    0
#define R_EC_P224    1
#define R_EC_P256    2
#define R_EC_P384    3
#define R_EC_P521    4
#define R_EC_K163    5
#define R_EC_K233    6
#define R_EC_K283    7
#define R_EC_K409    8
#define R_EC_K571    9
#define R_EC_B163    10
#define R_EC_B233    11
#define R_EC_B283    12
#define R_EC_B409    13
#define R_EC_B571    14

#ifndef OPENSSL_NO_RSA
	RSA *rsa_key[RSA_NUM];
	long rsa_c[RSA_NUM][2];
@@ -492,8 +550,81 @@ int MAIN(int argc, char **argv)
	long dsa_c[DSA_NUM][2];
	static unsigned int dsa_bits[DSA_NUM]={512,1024,2048};
#endif
#ifndef OPENSSL_NO_EC
	/* We only test over the following curves as they are representative, 
	 * To add tests over more curves, simply add the curve NID
	 * and curve name to the following arrays and increase the 
	 * EC_NUM value accordingly. 
	 */
	static unsigned int test_curves[EC_NUM] = 
	{	
	/* Prime Curves */
	EC_GROUP_SECG_PRIME_160R1,
	EC_GROUP_NIST_PRIME_224,
	EC_GROUP_NIST_PRIME_256,
	EC_GROUP_NIST_PRIME_384,
	EC_GROUP_NIST_PRIME_521,
	/* Binary Curves */
	EC_GROUP_NIST_CHAR2_K163,
	EC_GROUP_NIST_CHAR2_K233,
	EC_GROUP_NIST_CHAR2_K283,
	EC_GROUP_NIST_CHAR2_K409,
	EC_GROUP_NIST_CHAR2_K571,
	EC_GROUP_NIST_CHAR2_B163,
	EC_GROUP_NIST_CHAR2_B233,
	EC_GROUP_NIST_CHAR2_B283,
	EC_GROUP_NIST_CHAR2_B409,
	EC_GROUP_NIST_CHAR2_B571
	}; 
	static char * test_curves_names[EC_NUM] = 
	{
	/* Prime Curves */
	"secp160r1",
	"nistp224",
	"nistp256",
	"nistp384",
	"nistp521",
	/* Binary Curves */
	"nistk163",
	"nistk233",
	"nistk283",
	"nistk409",
	"nistk571",
	"nistb163",
	"nistb233",
	"nistb283",
	"nistb409",
	"nistb571"
	};
	static int test_curves_bits[EC_NUM] =
        {
        160, 224, 256, 384, 521,
        163, 233, 283, 409, 571,
        163, 233, 283, 409, 571
        };

#endif

#ifndef OPENSSL_NO_ECDSA
        unsigned char ecdsasig[256];
        unsigned int ecdsasiglen;
        EC_KEY *ecdsa[EC_NUM];
        long ecdsa_c[EC_NUM][2];
#endif

#ifndef OPENSSL_NO_ECDH
        EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
        unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
        int secret_size_a, secret_size_b;
        int ecdh_check = 0;
        int secret_idx = 0;
        long ecdh_c[EC_NUM][2];
#endif

	int rsa_doit[RSA_NUM];
	int dsa_doit[DSA_NUM];
	int ecdsa_doit[EC_NUM];
        int ecdh_doit[EC_NUM];
	int doit[ALGOR_NUM];
	int pr_header=0;
	const EVP_CIPHER *evp_cipher=NULL;
@@ -512,6 +643,17 @@ int MAIN(int argc, char **argv)
#ifndef OPENSSL_NO_DSA
	memset(dsa_key,0,sizeof(dsa_key));
#endif
#ifndef OPENSSL_NO_ECDSA
	for (i=0; i<EC_NUM; i++) ecdsa[i] = NULL;
#endif
#ifndef OPENSSL_NO_ECDH
	for (i=0; i<EC_NUM; i++)
		{
		ecdh_a[i] = NULL;
		ecdh_b[i] = NULL;
		}
#endif


	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
@@ -550,6 +692,15 @@ int MAIN(int argc, char **argv)
		rsa_doit[i]=0;
	for (i=0; i<DSA_NUM; i++)
		dsa_doit[i]=0;
#ifndef OPENSSL_NO_ECDSA
	for (i=0; i<EC_NUM; i++)
		ecdsa_doit[i]=0;
#endif
#ifndef OPENSSL_NO_ECDH
	for (i=0; i<EC_NUM; i++)
		ecdh_doit[i]=0;
#endif

	
	j=0;
	argc--;
@@ -768,6 +919,52 @@ int MAIN(int argc, char **argv)
			dsa_doit[R_DSA_1024]=1;
			}
		else
#endif
#ifndef OPENSSL_NO_ECDSA
		     if (strcmp(*argv,"ecdsap160") == 0) ecdsa_doit[R_EC_P160]=2;
		else if (strcmp(*argv,"ecdsap224") == 0) ecdsa_doit[R_EC_P224]=2;
		else if (strcmp(*argv,"ecdsap256") == 0) ecdsa_doit[R_EC_P256]=2;
		else if (strcmp(*argv,"ecdsap384") == 0) ecdsa_doit[R_EC_P384]=2;
		else if (strcmp(*argv,"ecdsap521") == 0) ecdsa_doit[R_EC_P521]=2;
		else if (strcmp(*argv,"ecdsak163") == 0) ecdsa_doit[R_EC_K163]=2;
		else if (strcmp(*argv,"ecdsak233") == 0) ecdsa_doit[R_EC_K233]=2;
		else if (strcmp(*argv,"ecdsak283") == 0) ecdsa_doit[R_EC_K283]=2;
		else if (strcmp(*argv,"ecdsak409") == 0) ecdsa_doit[R_EC_K409]=2;
		else if (strcmp(*argv,"ecdsak571") == 0) ecdsa_doit[R_EC_K571]=2;
		else if (strcmp(*argv,"ecdsab163") == 0) ecdsa_doit[R_EC_B163]=2;
		else if (strcmp(*argv,"ecdsab233") == 0) ecdsa_doit[R_EC_B233]=2;
		else if (strcmp(*argv,"ecdsab283") == 0) ecdsa_doit[R_EC_B283]=2;
		else if (strcmp(*argv,"ecdsab409") == 0) ecdsa_doit[R_EC_B409]=2;
		else if (strcmp(*argv,"ecdsab571") == 0) ecdsa_doit[R_EC_B571]=2;
		else if (strcmp(*argv,"ecdsa") == 0)
			{
			for (i=0; i < EC_NUM; i++)
				ecdsa_doit[i]=1;
			}
		else
#endif
#ifndef OPENSSL_NO_ECDH
		     if (strcmp(*argv,"ecdhp160") == 0) ecdh_doit[R_EC_P160]=2;
		else if (strcmp(*argv,"ecdhp224") == 0) ecdh_doit[R_EC_P224]=2;
		else if (strcmp(*argv,"ecdhp256") == 0) ecdh_doit[R_EC_P256]=2;
		else if (strcmp(*argv,"ecdhp384") == 0) ecdh_doit[R_EC_P384]=2;
		else if (strcmp(*argv,"ecdhp521") == 0) ecdh_doit[R_EC_P521]=2;
		else if (strcmp(*argv,"ecdhk163") == 0) ecdh_doit[R_EC_K163]=2;
		else if (strcmp(*argv,"ecdhk233") == 0) ecdh_doit[R_EC_K233]=2;
		else if (strcmp(*argv,"ecdhk283") == 0) ecdh_doit[R_EC_K283]=2;
		else if (strcmp(*argv,"ecdhk409") == 0) ecdh_doit[R_EC_K409]=2;
		else if (strcmp(*argv,"ecdhk571") == 0) ecdh_doit[R_EC_K571]=2;
		else if (strcmp(*argv,"ecdhb163") == 0) ecdh_doit[R_EC_B163]=2;
		else if (strcmp(*argv,"ecdhb233") == 0) ecdh_doit[R_EC_B233]=2;
		else if (strcmp(*argv,"ecdhb283") == 0) ecdh_doit[R_EC_B283]=2;
		else if (strcmp(*argv,"ecdhb409") == 0) ecdh_doit[R_EC_B409]=2;
		else if (strcmp(*argv,"ecdhb571") == 0) ecdh_doit[R_EC_B571]=2;
		else if (strcmp(*argv,"ecdh") == 0)
			{
			for (i=0; i < EC_NUM; i++)
				ecdh_doit[i]=1;
			}
		else
#endif
			{
			BIO_printf(bio_err,"Error: bad option or value\n");
@@ -834,6 +1031,18 @@ int MAIN(int argc, char **argv)
#ifndef OPENSSL_NO_DSA
			BIO_printf(bio_err,"dsa512   dsa1024  dsa2048\n");
#endif
#ifndef OPENSSL_NO_ECDSA
			BIO_printf(bio_err,"ecdsap160 ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
			BIO_printf(bio_err,"ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n");
			BIO_printf(bio_err,"ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571\n");
			BIO_printf(bio_err,"ecdsa\n");
#endif
#ifndef OPENSSL_NO_ECDH
			BIO_printf(bio_err,"ecdhp160  ecdhp224  ecdhp256  ecdhp384  ecdhp521\n");
			BIO_printf(bio_err,"ecdhk163  ecdhk233  ecdhk283  ecdhk409  ecdhk571\n");
			BIO_printf(bio_err,"ecdhb163  ecdhb233  ecdhb283  ecdhb409  ecdhb571\n");
			BIO_printf(bio_err,"ecdh\n");
#endif

#ifndef OPENSSL_NO_IDEA
			BIO_printf(bio_err,"idea     ");
@@ -1063,6 +1272,114 @@ int MAIN(int argc, char **argv)
		}
#endif

#ifndef OPENSSL_NO_ECDSA
	ecdsa_c[R_EC_P160][0]=count/1000;
	ecdsa_c[R_EC_P160][1]=count/1000/2;
	for (i=R_EC_P224; i<=R_EC_P521; i++)
		{
		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
			ecdsa_doit[i]=0;
		else
			{
			if (ecdsa_c[i] == 0)
				{
				ecdsa_c[i][0]=1;
				ecdsa_c[i][1]=1;
				}
			}
		}
	ecdsa_c[R_EC_K163][0]=count/1000;
	ecdsa_c[R_EC_K163][1]=count/1000/2;
	for (i=R_EC_K233; i<=R_EC_K571; i++)
		{
		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
			ecdsa_doit[i]=0;
		else
			{
			if (ecdsa_c[i] == 0)
				{
				ecdsa_c[i][0]=1;
				ecdsa_c[i][1]=1;
				}
			}
		}
	ecdsa_c[R_EC_B163][0]=count/1000;
	ecdsa_c[R_EC_B163][1]=count/1000/2;
	for (i=R_EC_B233; i<=R_EC_B571; i++)
		{
		ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
		ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
		if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
			ecdsa_doit[i]=0;
		else
			{
			if (ecdsa_c[i] == 0)
				{
				ecdsa_c[i][0]=1;
				ecdsa_c[i][1]=1;
				}
			}
		}
#endif

#ifndef OPENSSL_NO_ECDH
	ecdh_c[R_EC_P160][0]=count/1000;
	ecdh_c[R_EC_P160][1]=count/1000;
	for (i=R_EC_P224; i<=R_EC_P521; i++)
		{
		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
			ecdh_doit[i]=0;
		else
			{
			if (ecdh_c[i] == 0)
				{
				ecdh_c[i][0]=1;
				ecdh_c[i][1]=1;
				}
			}
		}
	ecdh_c[R_EC_K163][0]=count/1000;
	ecdh_c[R_EC_K163][1]=count/1000;
	for (i=R_EC_K233; i<=R_EC_K571; i++)
		{
		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
			ecdh_doit[i]=0;
		else
			{
			if (ecdh_c[i] == 0)
				{
				ecdh_c[i][0]=1;
				ecdh_c[i][1]=1;
				}
			}
		}
	ecdh_c[R_EC_B163][0]=count/1000;
	ecdh_c[R_EC_B163][1]=count/1000;
	for (i=R_EC_B233; i<=R_EC_B571; i++)
		{
		ecdh_c[i][0]=ecdh_c[i-1][0]/2;
		ecdh_c[i][1]=ecdh_c[i-1][1]/2;
		if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
			ecdh_doit[i]=0;
		else
			{
			if (ecdh_c[i] == 0)
				{
				ecdh_c[i][0]=1;
				ecdh_c[i][1]=1;
				}
			}
		}
#endif

#define COND(d)	(count < (d))
#define COUNT(d) (d)
#else
@@ -1587,6 +1904,215 @@ int MAIN(int argc, char **argv)
		}
	if (rnd_fake) RAND_cleanup();
#endif

#ifndef OPENSSL_NO_ECDSA
	if (RAND_status() != 1) 
		{
		RAND_seed(rnd_seed, sizeof rnd_seed);
		rnd_fake = 1;
		}
	for (j=0; j<EC_NUM; j++) 
		{
		int ret;

		if (!ecdsa_doit[j]) continue; /* Ignore Curve */ 
		ecdsa[j] = EC_KEY_new();
		if (ecdsa[j] == NULL) 
			{
			BIO_printf(bio_err,"ECDSA failure.\n");
			ERR_print_errors(bio_err);
			rsa_count=1;
			} 
		else 
			{
			ecdsa[j]->group = EC_GROUP_new_by_nid(test_curves[j]);
			/* Could not obtain group information */
			if (ecdsa[j]->group == NULL) 
				{
				BIO_printf(bio_err,"ECDSA failure.Could not obtain group information\n");
				ERR_print_errors(bio_err);
				rsa_count=1;
				} 
			else 
				{
				/* Perform ECDSA signature test */
				EC_KEY_generate_key(ecdsa[j]);
				ret = ECDSA_sign(EVP_PKEY_ECDSA, buf, 20, ecdsasig, 
					&ecdsasiglen, ecdsa[j]);
				if (ret == 0) 
					{
					BIO_printf(bio_err,"ECDSA sign failure.  No ECDSA sign will be done.\n");
					ERR_print_errors(bio_err);
					rsa_count=1;
					} 
				else 
					{
					pkey_print_message("sign","ecdsa",
						ecdsa_c[j][0], 
						test_curves_bits[j],
						ECDSA_SECONDS);

					Time_F(START);
					for (count=0,run=1; COND(ecdsa_c[j][0]); count++) 
						{
						ret=ECDSA_sign(EVP_PKEY_ECDSA, buf, 20, ecdsasig, &ecdsasiglen, ecdsa[j]);
						if (ret == 0) 
							{
							BIO_printf(bio_err, "ECDSA sign failure\n");
							ERR_print_errors(bio_err);
							count=1;
							break;
							}
						}
						d=Time_F(STOP);

						BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
						"%ld %d bit ECDSA signs in %.2fs \n", 
						count, test_curves_bits[j], d);
						ecdsa_results[j][0]=d/(double)count;
						rsa_count=count;
					}

				/* Perform ECDSA verification test */
				ret=ECDSA_verify(EVP_PKEY_ECDSA, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
				if (ret != 1) 
					{
					BIO_printf(bio_err,"ECDSA verify failure.  No ECDSA verify will be done.\n");
					ERR_print_errors(bio_err);
					ecdsa_doit[j] = 0;
					} 
				else 
					{
					pkey_print_message("verify","ecdsa",
					ecdsa_c[j][1],
					test_curves_bits[j],
					ECDSA_SECONDS);
					Time_F(START);
					for (count=0,run=1; COND(ecdsa_c[j][1]); count++) 
						{
						ret=ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
						if (ret != 1) 
							{
							BIO_printf(bio_err, "ECDSA verify failure\n");
							ERR_print_errors(bio_err);
							count=1;
							break;
							}
						}
						d=Time_F(STOP);
						BIO_printf(bio_err, mr? "+R6:%ld:%d:%.2f\n"
							: "%ld %d bit ECDSA verify in %.2fs\n",
						count, test_curves_bits[j], d);
						ecdsa_results[j][1]=d/(double)count;
					}

				if (rsa_count <= 1) 
					{
					/* if longer than 10s, don't do any more */
					for (j++; j<EC_NUM; j++)
					ecdsa_doit[j]=0;
					}
				}
			}
		}
	if (rnd_fake) RAND_cleanup();
#endif

#ifndef OPENSSL_NO_ECDH
	if (RAND_status() != 1)
		{
		RAND_seed(rnd_seed, sizeof rnd_seed);
		rnd_fake = 1;
		}
	for (j=0; j<EC_NUM; j++)
		{
		if (!ecdh_doit[j]) continue;
		ecdh_a[j] = EC_KEY_new();
		ecdh_b[j] = EC_KEY_new();
		if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL))
			{
			BIO_printf(bio_err,"ECDH failure.\n");
			ERR_print_errors(bio_err);
			rsa_count=1;
			}
		else
			{
			ecdh_a[j]->group = EC_GROUP_new_by_nid(test_curves[j]);
			if (ecdh_a[j]->group == NULL)
				{
				BIO_printf(bio_err,"ECDH failure.\n");
				ERR_print_errors(bio_err);
				rsa_count=1;
				}
			else
				{
				ecdh_b[j]->group = ecdh_a[j]->group;

				/* generate two ECDH key pairs */
				if (!EC_KEY_generate_key(ecdh_a[j]) ||
					!EC_KEY_generate_key(ecdh_b[j]))
					{
					BIO_printf(bio_err,"ECDH key generation failure.\n");
					ERR_print_errors(bio_err);
					rsa_count=1;		
					}
				else
					{
					secret_size_a = ECDH_compute_key(secret_a, 
						ecdh_b[j]->pub_key,
						ecdh_a[j]);
					secret_size_b = ECDH_compute_key(secret_b, 
						ecdh_a[j]->pub_key,
						ecdh_b[j]);
					if (secret_size_a != secret_size_b) 
						ecdh_check = 0;
					else
						ecdh_check = 1;

					for (secret_idx = 0; 
					    (secret_idx < secret_size_a) && (ecdh_check == 1);
					    secret_idx++)
						{
						if (secret_a[secret_idx] != secret_b[secret_idx])
						ecdh_check = 0;
						}

					if (ecdh_check == 0)
						{
						BIO_printf(bio_err,"ECDH computations don't match.\n");
						ERR_print_errors(bio_err);
						rsa_count=1;		
						}

					pkey_print_message("","ecdh",
					ecdh_c[j][0], 
					test_curves_bits[j],
					ECDH_SECONDS);
					Time_F(START);
					for (count=0,run=1; COND(ecdh_c[j][0]); count++)
						{
						ECDH_compute_key(secret_a, 
						ecdh_b[j]->pub_key,
						ecdh_a[j]);
						}
					d=Time_F(STOP);
					BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" :"%ld %d-bit ECDH ops in %.2fs\n",
					count, test_curves_bits[j], d);
					ecdh_results[j][0]=d/(double)count;
					rsa_count=count;
					}
				}
			}

		if (rsa_count <= 1)
			{
			/* if longer than 10s, don't do any more */
			for (j++; j<EC_NUM; j++)
			ecdh_doit[j]=0;
			}
		}
	if (rnd_fake) RAND_cleanup();
#endif
#ifdef HAVE_FORK
show_res:
#endif
@@ -1712,7 +2238,57 @@ show_res:
				1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
		}
#endif
#ifndef OPENSSL_NO_ECDSA
	j=1;
	for (k=0; k<EC_NUM; k++)
		{
		if (!ecdsa_doit[k]) continue;
		if (j && !mr)
			{
			printf("%30ssign    verify    sign/s verify/s\n"," ");
			j=0;
			}

		if (mr)
			fprintf(stdout,"+F4:%u:%u:%f:%f\n", 
				k, test_curves_bits[k],
				ecdsa_results[k][0],ecdsa_results[k][1]);
		else
			fprintf(stdout,
				"%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n", 
				test_curves_bits[k],
				test_curves_names[k],
				ecdsa_results[k][0],ecdsa_results[k][1], 
				1.0/ecdsa_results[k][0],1.0/ecdsa_results[k][1]);
		}
#endif


#ifndef OPENSSL_NO_ECDH
	j=1;
	for (k=0; k<EC_NUM; k++)
		{
		if (!ecdh_doit[k]) continue;
		if (j && !mr)
			{
			printf("%30sop      op/s\n"," ");
			j=0;
			}
		if (mr)
			fprintf(stdout,"+F5:%u:%u:%f:%f\n",
				k, test_curves_bits[k],
				ecdh_results[k][0], 1.0/ecdh_results[k][0]);

		else
			fprintf(stdout,"%4u bit ecdh (%s) %8.4fs %8.1f\n",
				test_curves_bits[k],
				test_curves_names[k],
				ecdh_results[k][0], 1.0/ecdh_results[k][0]);
		}
#endif

	mret=0;

end:
	ERR_print_errors(bio_err);
	if (buf != NULL) OPENSSL_free(buf);
@@ -1727,6 +2303,22 @@ end:
		if (dsa_key[i] != NULL)
			DSA_free(dsa_key[i]);
#endif

#ifndef OPENSSL_NO_ECDSA
	for (i=0; i<EC_NUM; i++)
		if (ecdsa[i] != NULL)
			EC_KEY_free(ecdsa[i]);
#endif
#ifndef OPENSSL_NO_ECDH
	for (i=0; i<EC_NUM; i++)
	{
		if (ecdh_a[i] != NULL)
			EC_KEY_free(ecdh_a[i]);
		if (ecdh_b[i] != NULL)
			EC_KEY_free(ecdh_b[i]);
	}
#endif

	apps_shutdown();
	EXIT(mret);
	}
@@ -1928,6 +2520,49 @@ static int do_multi(int multi)
				else
					dsa_results[k][1]=d;
				}
#ifndef OPENSSL_NO_ECDSA
			else if(!strncmp(buf,"+F4:",4))
				{
				int k;
				double d;
				
				p=buf+4;
				k=atoi(sstrsep(&p,sep));
				sstrsep(&p,sep);

				d=atof(sstrsep(&p,sep));
				if(n)
					ecdsa_results[k][0]=1/(1/ecdsa_results[k][0]+1/d);
				else
					ecdsa_results[k][0]=d;

				d=atof(sstrsep(&p,sep));
				if(n)
					ecdsa_results[k][1]=1/(1/ecdsa_results[k][1]+1/d);
				else
					ecdsa_results[k][1]=d;
				}
#endif 

#ifndef OPENSSL_NO_ECDH
			else if(!strncmp(buf,"+F5:",4))
				{
				int k;
				double d;
				
				p=buf+4;
				k=atoi(sstrsep(&p,sep));
				sstrsep(&p,sep);

				d=atof(sstrsep(&p,sep));
				if(n)
					ecdh_results[k][0]=1/(1/ecdh_results[k][0]+1/d);
				else
					ecdh_results[k][0]=d;

				}
#endif

			else if(!strncmp(buf,"+H:",3))
				{
				}
Loading