speed.c revision 55714
1/* apps/speed.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59/* most of this code has been pilfered from my libdes speed.c program */
60
61#undef SECONDS
62#define SECONDS		3
63#define RSA_SECONDS	10
64#define DSA_SECONDS	10
65
66/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */
67/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */
68
69#undef PROG
70#define PROG speed_main
71
72#include <stdio.h>
73#include <stdlib.h>
74#include <signal.h>
75#include <string.h>
76#include <math.h>
77#include "apps.h"
78#ifdef NO_STDIO
79#define APPS_WIN16
80#endif
81#include <openssl/crypto.h>
82#include <openssl/rand.h>
83#include <openssl/err.h>
84
85#if !defined(MSDOS) && (!defined(VMS) || defined(__DECC))
86#define TIMES
87#endif
88
89#ifndef _IRIX
90#include <time.h>
91#endif
92#ifdef TIMES
93#include <sys/types.h>
94#include <sys/times.h>
95#endif
96
97/* Depending on the VMS version, the tms structure is perhaps defined.
98   The __TMS macro will show if it was.  If it wasn't defined, we should
99   undefine TIMES, since that tells the rest of the program how things
100   should be handled.				-- Richard Levitte */
101#if defined(VMS) && defined(__DECC) && !defined(__TMS)
102#undef TIMES
103#endif
104
105#ifndef TIMES
106#include <sys/timeb.h>
107#endif
108
109#if defined(sun) || defined(__ultrix)
110#define _POSIX_SOURCE
111#include <limits.h>
112#include <sys/param.h>
113#endif
114
115#ifndef NO_DES
116#include <openssl/des.h>
117#endif
118#ifndef NO_MD2
119#include <openssl/md2.h>
120#endif
121#ifndef NO_MDC2
122#include <openssl/mdc2.h>
123#endif
124#ifndef NO_MD5
125#include <openssl/md5.h>
126#endif
127#ifndef NO_HMAC
128#include <openssl/hmac.h>
129#endif
130#include <openssl/evp.h>
131#ifndef NO_SHA
132#include <openssl/sha.h>
133#endif
134#ifndef NO_RIPEMD
135#include <openssl/ripemd.h>
136#endif
137#ifndef NO_RC4
138#include <openssl/rc4.h>
139#endif
140#ifndef NO_RC5
141#include <openssl/rc5.h>
142#endif
143#ifndef NO_RC2
144#include <openssl/rc2.h>
145#endif
146#ifndef NO_IDEA
147#include <openssl/idea.h>
148#endif
149#ifndef NO_BF
150#include <openssl/blowfish.h>
151#endif
152#ifndef NO_CAST
153#include <openssl/cast.h>
154#endif
155#ifndef NO_RSA
156#include <openssl/rsa.h>
157#include "./testrsa.h"
158#endif
159#include <openssl/x509.h>
160#ifndef NO_DSA
161#include "./testdsa.h"
162#endif
163
164/* The following if from times(3) man page.  It may need to be changed */
165#ifndef HZ
166# ifndef CLK_TCK
167#  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
168#   define HZ	100.0
169#  else /* _BSD_CLK_TCK_ */
170#   define HZ ((double)_BSD_CLK_TCK_)
171#  endif
172# else /* CLK_TCK */
173#  define HZ ((double)CLK_TCK)
174# endif
175#endif
176
177#undef BUFSIZE
178#define BUFSIZE	((long)1024*8+1)
179int run=0;
180
181static double Time_F(int s);
182static void print_message(char *s,long num,int length);
183static void pkey_print_message(char *str,char *str2,long num,int bits,int sec);
184#ifdef SIGALRM
185#if defined(__STDC__) || defined(sgi) || defined(_AIX)
186#define SIGRETTYPE void
187#else
188#define SIGRETTYPE int
189#endif
190
191static SIGRETTYPE sig_done(int sig);
192static SIGRETTYPE sig_done(int sig)
193	{
194	signal(SIGALRM,sig_done);
195	run=0;
196#ifdef LINT
197	sig=sig;
198#endif
199	}
200#endif
201
202#define START	0
203#define STOP	1
204
205static double Time_F(int s)
206	{
207	double ret;
208#ifdef TIMES
209	static struct tms tstart,tend;
210
211	if (s == START)
212		{
213		times(&tstart);
214		return(0);
215		}
216	else
217		{
218		times(&tend);
219		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
220		return((ret < 1e-3)?1e-3:ret);
221		}
222#else /* !times() */
223	static struct timeb tstart,tend;
224	long i;
225
226	if (s == START)
227		{
228		ftime(&tstart);
229		return(0);
230		}
231	else
232		{
233		ftime(&tend);
234		i=(long)tend.millitm-(long)tstart.millitm;
235		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
236		return((ret < 0.001)?0.001:ret);
237		}
238#endif
239	}
240
241int MAIN(int argc, char **argv)
242	{
243	unsigned char *buf=NULL,*buf2=NULL;
244	int ret=1;
245#define ALGOR_NUM	14
246#define SIZE_NUM	5
247#define RSA_NUM		4
248#define DSA_NUM		3
249	long count,rsa_count;
250	int i,j,k,rsa_num,rsa_num2;
251#ifndef NO_MD2
252	unsigned char md2[MD2_DIGEST_LENGTH];
253#endif
254#ifndef NO_MDC2
255	unsigned char mdc2[MDC2_DIGEST_LENGTH];
256#endif
257#ifndef NO_MD5
258	unsigned char md5[MD5_DIGEST_LENGTH];
259	unsigned char hmac[MD5_DIGEST_LENGTH];
260#endif
261#ifndef NO_SHA
262	unsigned char sha[SHA_DIGEST_LENGTH];
263#endif
264#ifndef NO_RIPEMD
265	unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
266#endif
267#ifndef NO_RC4
268	RC4_KEY rc4_ks;
269#endif
270#ifndef NO_RC5
271	RC5_32_KEY rc5_ks;
272#endif
273#ifndef NO_RC2
274	RC2_KEY rc2_ks;
275#endif
276#ifndef NO_IDEA
277	IDEA_KEY_SCHEDULE idea_ks;
278#endif
279#ifndef NO_BF
280	BF_KEY bf_ks;
281#endif
282#ifndef NO_CAST
283	CAST_KEY cast_ks;
284#endif
285	static unsigned char key16[16]=
286		{0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
287		 0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
288	unsigned char iv[8];
289#ifndef NO_DES
290	des_cblock *buf_as_des_cblock = NULL;
291	static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
292	static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
293	static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
294	des_key_schedule sch,sch2,sch3;
295#endif
296#define	D_MD2		0
297#define	D_MDC2		1
298#define	D_MD5		2
299#define	D_HMAC		3
300#define	D_SHA1		4
301#define D_RMD160	5
302#define	D_RC4		6
303#define	D_CBC_DES	7
304#define	D_EDE3_DES	8
305#define	D_CBC_IDEA	9
306#define	D_CBC_RC2	10
307#define	D_CBC_RC5	11
308#define	D_CBC_BF	12
309#define	D_CBC_CAST	13
310	double d,results[ALGOR_NUM][SIZE_NUM];
311	static int lengths[SIZE_NUM]={8,64,256,1024,8*1024};
312	long c[ALGOR_NUM][SIZE_NUM];
313	static char *names[ALGOR_NUM]={
314		"md2","mdc2","md5","hmac(md5)","sha1","rmd160","rc4",
315		"des cbc","des ede3","idea cbc",
316		"rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc"};
317#define	R_DSA_512	0
318#define	R_DSA_1024	1
319#define	R_DSA_2048	2
320#define	R_RSA_512	0
321#define	R_RSA_1024	1
322#define	R_RSA_2048	2
323#define	R_RSA_4096	3
324#ifndef NO_RSA
325	RSA *rsa_key[RSA_NUM];
326	long rsa_c[RSA_NUM][2];
327	double rsa_results[RSA_NUM][2];
328	static unsigned int rsa_bits[RSA_NUM]={512,1024,2048,4096};
329	static unsigned char *rsa_data[RSA_NUM]=
330		{test512,test1024,test2048,test4096};
331	static int rsa_data_length[RSA_NUM]={
332		sizeof(test512),sizeof(test1024),
333		sizeof(test2048),sizeof(test4096)};
334#endif
335#ifndef NO_DSA
336	DSA *dsa_key[DSA_NUM];
337	long dsa_c[DSA_NUM][2];
338	double dsa_results[DSA_NUM][2];
339	static unsigned int dsa_bits[DSA_NUM]={512,1024,2048};
340#endif
341	int rsa_doit[RSA_NUM];
342	int dsa_doit[DSA_NUM];
343	int doit[ALGOR_NUM];
344	int pr_header=0;
345
346	apps_startup();
347#ifndef NO_DSA
348	memset(dsa_key,0,sizeof(dsa_key));
349#endif
350
351	if (bio_err == NULL)
352		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
353			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
354
355#ifndef NO_RSA
356	memset(rsa_key,0,sizeof(rsa_key));
357	for (i=0; i<RSA_NUM; i++)
358		rsa_key[i]=NULL;
359#endif
360
361	if ((buf=(unsigned char *)Malloc((int)BUFSIZE)) == NULL)
362		{
363		BIO_printf(bio_err,"out of memory\n");
364		goto end;
365		}
366#ifndef NO_DES
367	buf_as_des_cblock = (des_cblock *)buf;
368#endif
369	if ((buf2=(unsigned char *)Malloc((int)BUFSIZE)) == NULL)
370		{
371		BIO_printf(bio_err,"out of memory\n");
372		goto end;
373		}
374
375	memset(c,0,sizeof(c));
376	memset(iv,0,sizeof(iv));
377
378	for (i=0; i<ALGOR_NUM; i++)
379		doit[i]=0;
380	for (i=0; i<RSA_NUM; i++)
381		rsa_doit[i]=0;
382	for (i=0; i<DSA_NUM; i++)
383		dsa_doit[i]=0;
384
385	j=0;
386	argc--;
387	argv++;
388	while (argc)
389		{
390#ifndef NO_MD2
391		if	(strcmp(*argv,"md2") == 0) doit[D_MD2]=1;
392		else
393#endif
394#ifndef NO_MDC2
395			if (strcmp(*argv,"mdc2") == 0) doit[D_MDC2]=1;
396		else
397#endif
398#ifndef NO_MD5
399			if (strcmp(*argv,"md5") == 0) doit[D_MD5]=1;
400		else
401#endif
402#ifndef NO_MD5
403			if (strcmp(*argv,"hmac") == 0) doit[D_HMAC]=1;
404		else
405#endif
406#ifndef NO_SHA
407			if (strcmp(*argv,"sha1") == 0) doit[D_SHA1]=1;
408		else
409			if (strcmp(*argv,"sha") == 0) doit[D_SHA1]=1;
410		else
411#endif
412#ifndef NO_RIPEMD
413			if (strcmp(*argv,"ripemd") == 0) doit[D_RMD160]=1;
414		else
415			if (strcmp(*argv,"rmd160") == 0) doit[D_RMD160]=1;
416		else
417			if (strcmp(*argv,"ripemd160") == 0) doit[D_RMD160]=1;
418		else
419#endif
420#ifndef NO_RC4
421			if (strcmp(*argv,"rc4") == 0) doit[D_RC4]=1;
422		else
423#endif
424#ifndef NO_DEF
425			if (strcmp(*argv,"des-cbc") == 0) doit[D_CBC_DES]=1;
426		else	if (strcmp(*argv,"des-ede3") == 0) doit[D_EDE3_DES]=1;
427		else
428#endif
429#ifndef NO_RSA
430#ifdef RSAref
431			if (strcmp(*argv,"rsaref") == 0)
432			{
433			RSA_set_default_method(RSA_PKCS1_RSAref());
434			j--;
435			}
436		else
437#endif
438			if (strcmp(*argv,"openssl") == 0)
439			{
440			RSA_set_default_method(RSA_PKCS1_SSLeay());
441			j--;
442			}
443		else
444#endif /* !NO_RSA */
445		     if (strcmp(*argv,"dsa512") == 0) dsa_doit[R_DSA_512]=2;
446		else if (strcmp(*argv,"dsa1024") == 0) dsa_doit[R_DSA_1024]=2;
447		else if (strcmp(*argv,"dsa2048") == 0) dsa_doit[R_DSA_2048]=2;
448		else if (strcmp(*argv,"rsa512") == 0) rsa_doit[R_RSA_512]=2;
449		else if (strcmp(*argv,"rsa1024") == 0) rsa_doit[R_RSA_1024]=2;
450		else if (strcmp(*argv,"rsa2048") == 0) rsa_doit[R_RSA_2048]=2;
451		else if (strcmp(*argv,"rsa4096") == 0) rsa_doit[R_RSA_4096]=2;
452		else
453#ifndef NO_RC2
454		     if (strcmp(*argv,"rc2-cbc") == 0) doit[D_CBC_RC2]=1;
455		else if (strcmp(*argv,"rc2") == 0) doit[D_CBC_RC2]=1;
456		else
457#endif
458#ifndef NO_RC5
459		     if (strcmp(*argv,"rc5-cbc") == 0) doit[D_CBC_RC5]=1;
460		else if (strcmp(*argv,"rc5") == 0) doit[D_CBC_RC5]=1;
461		else
462#endif
463#ifndef NO_IDEA
464		     if (strcmp(*argv,"idea-cbc") == 0) doit[D_CBC_IDEA]=1;
465		else if (strcmp(*argv,"idea") == 0) doit[D_CBC_IDEA]=1;
466		else
467#endif
468#ifndef NO_BF
469		     if (strcmp(*argv,"bf-cbc") == 0) doit[D_CBC_BF]=1;
470		else if (strcmp(*argv,"blowfish") == 0) doit[D_CBC_BF]=1;
471		else if (strcmp(*argv,"bf") == 0) doit[D_CBC_BF]=1;
472		else
473#endif
474#ifndef NO_CAST
475		     if (strcmp(*argv,"cast-cbc") == 0) doit[D_CBC_CAST]=1;
476		else if (strcmp(*argv,"cast") == 0) doit[D_CBC_CAST]=1;
477		else if (strcmp(*argv,"cast5") == 0) doit[D_CBC_CAST]=1;
478		else
479#endif
480#ifndef NO_DES
481			if (strcmp(*argv,"des") == 0)
482			{
483			doit[D_CBC_DES]=1;
484			doit[D_EDE3_DES]=1;
485			}
486		else
487#endif
488#ifndef NO_RSA
489			if (strcmp(*argv,"rsa") == 0)
490			{
491			rsa_doit[R_RSA_512]=1;
492			rsa_doit[R_RSA_1024]=1;
493			rsa_doit[R_RSA_2048]=1;
494			rsa_doit[R_RSA_4096]=1;
495			}
496		else
497#endif
498#ifndef NO_DSA
499			if (strcmp(*argv,"dsa") == 0)
500			{
501			dsa_doit[R_DSA_512]=1;
502			dsa_doit[R_DSA_1024]=1;
503			}
504		else
505#endif
506			{
507			BIO_printf(bio_err,"bad value, pick one of\n");
508			BIO_printf(bio_err,"md2      mdc2	md5      hmac      sha1    rmd160\n");
509#ifndef NO_IDEA
510			BIO_printf(bio_err,"idea-cbc ");
511#endif
512#ifndef NO_RC2
513			BIO_printf(bio_err,"rc2-cbc  ");
514#endif
515#ifndef NO_RC5
516			BIO_printf(bio_err,"rc5-cbc  ");
517#endif
518#ifndef NO_BF
519			BIO_printf(bio_err,"bf-cbc");
520#endif
521#if !defined(NO_IDEA) && !defined(NO_RC2) && !defined(NO_BF) && !defined(NO_RC5)
522			BIO_printf(bio_err,"\n");
523#endif
524			BIO_printf(bio_err,"des-cbc  des-ede3 ");
525#ifndef NO_RC4
526			BIO_printf(bio_err,"rc4");
527#endif
528#ifndef NO_RSA
529			BIO_printf(bio_err,"\nrsa512   rsa1024  rsa2048  rsa4096\n");
530#endif
531#ifndef NO_DSA
532			BIO_printf(bio_err,"\ndsa512   dsa1024  dsa2048\n");
533#endif
534			BIO_printf(bio_err,"idea     rc2      des      rsa    blowfish\n");
535			goto end;
536			}
537		argc--;
538		argv++;
539		j++;
540		}
541
542	if (j == 0)
543		{
544		for (i=0; i<ALGOR_NUM; i++)
545			doit[i]=1;
546		for (i=0; i<RSA_NUM; i++)
547			rsa_doit[i]=1;
548		for (i=0; i<DSA_NUM; i++)
549			dsa_doit[i]=1;
550		}
551	for (i=0; i<ALGOR_NUM; i++)
552		if (doit[i]) pr_header++;
553
554#ifndef TIMES
555	BIO_printf(bio_err,"To get the most accurate results, try to run this\n");
556	BIO_printf(bio_err,"program when this computer is idle.\n");
557#endif
558
559#ifndef NO_RSA
560	for (i=0; i<RSA_NUM; i++)
561		{
562		unsigned char *p;
563
564		p=rsa_data[i];
565		rsa_key[i]=d2i_RSAPrivateKey(NULL,&p,rsa_data_length[i]);
566		if (rsa_key[i] == NULL)
567			{
568			BIO_printf(bio_err,"internal error loading RSA key number %d\n",i);
569			goto end;
570			}
571#if 0
572		else
573			{
574			BIO_printf(bio_err,"Loaded RSA key, %d bit modulus and e= 0x",BN_num_bits(rsa_key[i]->n));
575			BN_print(bio_err,rsa_key[i]->e);
576			BIO_printf(bio_err,"\n");
577			}
578#endif
579		}
580#endif
581
582#ifndef NO_DSA
583	dsa_key[0]=get_dsa512();
584	dsa_key[1]=get_dsa1024();
585	dsa_key[2]=get_dsa2048();
586#endif
587
588#ifndef NO_DES
589	des_set_key(&key,sch);
590	des_set_key(&key2,sch2);
591	des_set_key(&key3,sch3);
592#endif
593#ifndef NO_IDEA
594	idea_set_encrypt_key(key16,&idea_ks);
595#endif
596#ifndef NO_RC4
597	RC4_set_key(&rc4_ks,16,key16);
598#endif
599#ifndef NO_RC2
600	RC2_set_key(&rc2_ks,16,key16,128);
601#endif
602#ifndef NO_RC5
603	RC5_32_set_key(&rc5_ks,16,key16,12);
604#endif
605#ifndef NO_BF
606	BF_set_key(&bf_ks,16,key16);
607#endif
608#ifndef NO_CAST
609	CAST_set_key(&cast_ks,16,key16);
610#endif
611#ifndef NO_RSA
612	memset(rsa_c,0,sizeof(rsa_c));
613#endif
614#ifndef SIGALRM
615	BIO_printf(bio_err,"First we calculate the approximate speed ...\n");
616	count=10;
617	do	{
618		long i;
619		count*=2;
620		Time_F(START);
621		for (i=count; i; i--)
622			des_ecb_encrypt(buf_as_des_cblock,buf_as_des_cblock,
623				&(sch[0]),DES_ENCRYPT);
624		d=Time_F(STOP);
625		} while (d <3);
626	c[D_MD2][0]=count/10;
627	c[D_MDC2][0]=count/10;
628	c[D_MD5][0]=count;
629	c[D_HMAC][0]=count;
630	c[D_SHA1][0]=count;
631	c[D_RMD160][0]=count;
632	c[D_RC4][0]=count*5;
633	c[D_CBC_DES][0]=count;
634	c[D_EDE3_DES][0]=count/3;
635	c[D_CBC_IDEA][0]=count;
636	c[D_CBC_RC2][0]=count;
637	c[D_CBC_RC5][0]=count;
638	c[D_CBC_BF][0]=count;
639	c[D_CBC_CAST][0]=count;
640
641	for (i=1; i<SIZE_NUM; i++)
642		{
643		c[D_MD2][i]=c[D_MD2][0]*4*lengths[0]/lengths[i];
644		c[D_MDC2][i]=c[D_MDC2][0]*4*lengths[0]/lengths[i];
645		c[D_MD5][i]=c[D_MD5][0]*4*lengths[0]/lengths[i];
646		c[D_HMAC][i]=c[D_HMAC][0]*4*lengths[0]/lengths[i];
647		c[D_SHA1][i]=c[D_SHA1][0]*4*lengths[0]/lengths[i];
648		c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i];
649		}
650	for (i=1; i<SIZE_NUM; i++)
651		{
652		long l0,l1;
653
654		l0=(long)lengths[i-1];
655		l1=(long)lengths[i];
656		c[D_RC4][i]=c[D_RC4][i-1]*l0/l1;
657		c[D_CBC_DES][i]=c[D_CBC_DES][i-1]*l0/l1;
658		c[D_EDE3_DES][i]=c[D_EDE3_DES][i-1]*l0/l1;
659		c[D_CBC_IDEA][i]=c[D_CBC_IDEA][i-1]*l0/l1;
660		c[D_CBC_RC2][i]=c[D_CBC_RC2][i-1]*l0/l1;
661		c[D_CBC_RC5][i]=c[D_CBC_RC5][i-1]*l0/l1;
662		c[D_CBC_BF][i]=c[D_CBC_BF][i-1]*l0/l1;
663		c[D_CBC_CAST][i]=c[D_CBC_CAST][i-1]*l0/l1;
664		}
665#ifndef NO_RSA
666	rsa_c[R_RSA_512][0]=count/2000;
667	rsa_c[R_RSA_512][1]=count/400;
668	for (i=1; i<RSA_NUM; i++)
669		{
670		rsa_c[i][0]=rsa_c[i-1][0]/8;
671		rsa_c[i][1]=rsa_c[i-1][1]/4;
672		if ((rsa_doit[i] <= 1) && (rsa_c[i][0] == 0))
673			rsa_doit[i]=0;
674		else
675			{
676			if (rsa_c[i][0] == 0)
677				{
678				rsa_c[i][0]=1;
679				rsa_c[i][1]=20;
680				}
681			}
682		}
683#endif
684
685	dsa_c[R_DSA_512][0]=count/1000;
686	dsa_c[R_DSA_512][1]=count/1000/2;
687	for (i=1; i<DSA_NUM; i++)
688		{
689		dsa_c[i][0]=dsa_c[i-1][0]/4;
690		dsa_c[i][1]=dsa_c[i-1][1]/4;
691		if ((dsa_doit[i] <= 1) && (dsa_c[i][0] == 0))
692			dsa_doit[i]=0;
693		else
694			{
695			if (dsa_c[i] == 0)
696				{
697				dsa_c[i][0]=1;
698				dsa_c[i][1]=1;
699				}
700			}
701		}
702
703#define COND(d)	(count < (d))
704#define COUNT(d) (d)
705#else
706#define COND(c)	(run)
707#define COUNT(d) (count)
708	signal(SIGALRM,sig_done);
709#endif
710
711#ifndef NO_MD2
712	if (doit[D_MD2])
713		{
714		for (j=0; j<SIZE_NUM; j++)
715			{
716			print_message(names[D_MD2],c[D_MD2][j],lengths[j]);
717			Time_F(START);
718			for (count=0,run=1; COND(c[D_MD2][j]); count++)
719				MD2(buf,(unsigned long)lengths[j],&(md2[0]));
720			d=Time_F(STOP);
721			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
722				count,names[D_MD2],d);
723			results[D_MD2][j]=((double)count)/d*lengths[j];
724			}
725		}
726#endif
727#ifndef NO_MDC2
728	if (doit[D_MDC2])
729		{
730		for (j=0; j<SIZE_NUM; j++)
731			{
732			print_message(names[D_MDC2],c[D_MDC2][j],lengths[j]);
733			Time_F(START);
734			for (count=0,run=1; COND(c[D_MDC2][j]); count++)
735				MDC2(buf,(unsigned long)lengths[j],&(mdc2[0]));
736			d=Time_F(STOP);
737			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
738				count,names[D_MDC2],d);
739			results[D_MDC2][j]=((double)count)/d*lengths[j];
740			}
741		}
742#endif
743
744#ifndef NO_MD5
745	if (doit[D_MD5])
746		{
747		for (j=0; j<SIZE_NUM; j++)
748			{
749			print_message(names[D_MD5],c[D_MD5][j],lengths[j]);
750			Time_F(START);
751			for (count=0,run=1; COND(c[D_MD5][j]); count++)
752				MD5(&(buf[0]),(unsigned long)lengths[j],&(md5[0]));
753			d=Time_F(STOP);
754			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
755				count,names[D_MD5],d);
756			results[D_MD5][j]=((double)count)/d*lengths[j];
757			}
758		}
759#endif
760
761#if !defined(NO_MD5) && !defined(NO_HMAC)
762	if (doit[D_HMAC])
763		{
764		HMAC_CTX hctx;
765		HMAC_Init(&hctx,(unsigned char *)"This is a key...",
766			16,EVP_md5());
767
768		for (j=0; j<SIZE_NUM; j++)
769			{
770			print_message(names[D_HMAC],c[D_HMAC][j],lengths[j]);
771			Time_F(START);
772			for (count=0,run=1; COND(c[D_HMAC][j]); count++)
773				{
774				HMAC_Init(&hctx,NULL,0,NULL);
775                                HMAC_Update(&hctx,buf,lengths[j]);
776                                HMAC_Final(&hctx,&(hmac[0]),NULL);
777				}
778			d=Time_F(STOP);
779			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
780				count,names[D_HMAC],d);
781			results[D_HMAC][j]=((double)count)/d*lengths[j];
782			}
783		}
784#endif
785#ifndef NO_SHA
786	if (doit[D_SHA1])
787		{
788		for (j=0; j<SIZE_NUM; j++)
789			{
790			print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]);
791			Time_F(START);
792			for (count=0,run=1; COND(c[D_SHA1][j]); count++)
793				SHA1(buf,(unsigned long)lengths[j],&(sha[0]));
794			d=Time_F(STOP);
795			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
796				count,names[D_SHA1],d);
797			results[D_SHA1][j]=((double)count)/d*lengths[j];
798			}
799		}
800#endif
801#ifndef NO_RIPEMD
802	if (doit[D_RMD160])
803		{
804		for (j=0; j<SIZE_NUM; j++)
805			{
806			print_message(names[D_RMD160],c[D_RMD160][j],lengths[j]);
807			Time_F(START);
808			for (count=0,run=1; COND(c[D_RMD160][j]); count++)
809				RIPEMD160(buf,(unsigned long)lengths[j],&(rmd160[0]));
810			d=Time_F(STOP);
811			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
812				count,names[D_RMD160],d);
813			results[D_RMD160][j]=((double)count)/d*lengths[j];
814			}
815		}
816#endif
817#ifndef NO_RC4
818	if (doit[D_RC4])
819		{
820		for (j=0; j<SIZE_NUM; j++)
821			{
822			print_message(names[D_RC4],c[D_RC4][j],lengths[j]);
823			Time_F(START);
824			for (count=0,run=1; COND(c[D_RC4][j]); count++)
825				RC4(&rc4_ks,(unsigned int)lengths[j],
826					buf,buf);
827			d=Time_F(STOP);
828			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
829				count,names[D_RC4],d);
830			results[D_RC4][j]=((double)count)/d*lengths[j];
831			}
832		}
833#endif
834#ifndef NO_DES
835	if (doit[D_CBC_DES])
836		{
837		for (j=0; j<SIZE_NUM; j++)
838			{
839			print_message(names[D_CBC_DES],c[D_CBC_DES][j],lengths[j]);
840			Time_F(START);
841			for (count=0,run=1; COND(c[D_CBC_DES][j]); count++)
842				des_ncbc_encrypt(buf,buf,lengths[j],sch,
843						 &iv,DES_ENCRYPT);
844			d=Time_F(STOP);
845			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
846				count,names[D_CBC_DES],d);
847			results[D_CBC_DES][j]=((double)count)/d*lengths[j];
848			}
849		}
850
851	if (doit[D_EDE3_DES])
852		{
853		for (j=0; j<SIZE_NUM; j++)
854			{
855			print_message(names[D_EDE3_DES],c[D_EDE3_DES][j],lengths[j]);
856			Time_F(START);
857			for (count=0,run=1; COND(c[D_EDE3_DES][j]); count++)
858				des_ede3_cbc_encrypt(buf,buf,lengths[j],
859						     sch,sch2,sch3,
860						     &iv,DES_ENCRYPT);
861			d=Time_F(STOP);
862			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
863				count,names[D_EDE3_DES],d);
864			results[D_EDE3_DES][j]=((double)count)/d*lengths[j];
865			}
866		}
867#endif
868#ifndef NO_IDEA
869	if (doit[D_CBC_IDEA])
870		{
871		for (j=0; j<SIZE_NUM; j++)
872			{
873			print_message(names[D_CBC_IDEA],c[D_CBC_IDEA][j],lengths[j]);
874			Time_F(START);
875			for (count=0,run=1; COND(c[D_CBC_IDEA][j]); count++)
876				idea_cbc_encrypt(buf,buf,
877					(unsigned long)lengths[j],&idea_ks,
878					iv,IDEA_ENCRYPT);
879			d=Time_F(STOP);
880			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
881				count,names[D_CBC_IDEA],d);
882			results[D_CBC_IDEA][j]=((double)count)/d*lengths[j];
883			}
884		}
885#endif
886#ifndef NO_RC2
887	if (doit[D_CBC_RC2])
888		{
889		for (j=0; j<SIZE_NUM; j++)
890			{
891			print_message(names[D_CBC_RC2],c[D_CBC_RC2][j],lengths[j]);
892			Time_F(START);
893			for (count=0,run=1; COND(c[D_CBC_RC2][j]); count++)
894				RC2_cbc_encrypt(buf,buf,
895					(unsigned long)lengths[j],&rc2_ks,
896					iv,RC2_ENCRYPT);
897			d=Time_F(STOP);
898			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
899				count,names[D_CBC_RC2],d);
900			results[D_CBC_RC2][j]=((double)count)/d*lengths[j];
901			}
902		}
903#endif
904#ifndef NO_RC5
905	if (doit[D_CBC_RC5])
906		{
907		for (j=0; j<SIZE_NUM; j++)
908			{
909			print_message(names[D_CBC_RC5],c[D_CBC_RC5][j],lengths[j]);
910			Time_F(START);
911			for (count=0,run=1; COND(c[D_CBC_RC5][j]); count++)
912				RC5_32_cbc_encrypt(buf,buf,
913					(unsigned long)lengths[j],&rc5_ks,
914					iv,RC5_ENCRYPT);
915			d=Time_F(STOP);
916			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
917				count,names[D_CBC_RC5],d);
918			results[D_CBC_RC5][j]=((double)count)/d*lengths[j];
919			}
920		}
921#endif
922#ifndef NO_BF
923	if (doit[D_CBC_BF])
924		{
925		for (j=0; j<SIZE_NUM; j++)
926			{
927			print_message(names[D_CBC_BF],c[D_CBC_BF][j],lengths[j]);
928			Time_F(START);
929			for (count=0,run=1; COND(c[D_CBC_BF][j]); count++)
930				BF_cbc_encrypt(buf,buf,
931					(unsigned long)lengths[j],&bf_ks,
932					iv,BF_ENCRYPT);
933			d=Time_F(STOP);
934			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
935				count,names[D_CBC_BF],d);
936			results[D_CBC_BF][j]=((double)count)/d*lengths[j];
937			}
938		}
939#endif
940#ifndef NO_CAST
941	if (doit[D_CBC_CAST])
942		{
943		for (j=0; j<SIZE_NUM; j++)
944			{
945			print_message(names[D_CBC_CAST],c[D_CBC_CAST][j],lengths[j]);
946			Time_F(START);
947			for (count=0,run=1; COND(c[D_CBC_CAST][j]); count++)
948				CAST_cbc_encrypt(buf,buf,
949					(unsigned long)lengths[j],&cast_ks,
950					iv,CAST_ENCRYPT);
951			d=Time_F(STOP);
952			BIO_printf(bio_err,"%ld %s's in %.2fs\n",
953				count,names[D_CBC_CAST],d);
954			results[D_CBC_CAST][j]=((double)count)/d*lengths[j];
955			}
956		}
957#endif
958
959	RAND_bytes(buf,30);
960#ifndef NO_RSA
961	for (j=0; j<RSA_NUM; j++)
962		{
963		if (!rsa_doit[j]) continue;
964		rsa_num=RSA_private_encrypt(30,buf,buf2,rsa_key[j],
965			RSA_PKCS1_PADDING);
966		pkey_print_message("private","rsa",rsa_c[j][0],rsa_bits[j],
967			RSA_SECONDS);
968/*		RSA_blinding_on(rsa_key[j],NULL); */
969		Time_F(START);
970		for (count=0,run=1; COND(rsa_c[j][0]); count++)
971			{
972			rsa_num=RSA_private_encrypt(30,buf,buf2,rsa_key[j],
973				RSA_PKCS1_PADDING);
974			if (rsa_num <= 0)
975				{
976				BIO_printf(bio_err,"RSA private encrypt failure\n");
977				ERR_print_errors(bio_err);
978				count=1;
979				break;
980				}
981			}
982		d=Time_F(STOP);
983		BIO_printf(bio_err,"%ld %d bit private RSA's in %.2fs\n",
984			count,rsa_bits[j],d);
985		rsa_results[j][0]=d/(double)count;
986		rsa_count=count;
987
988#if 1
989		rsa_num2=RSA_public_decrypt(rsa_num,buf2,buf,rsa_key[j],
990			RSA_PKCS1_PADDING);
991		pkey_print_message("public","rsa",rsa_c[j][1],rsa_bits[j],
992			RSA_SECONDS);
993		Time_F(START);
994		for (count=0,run=1; COND(rsa_c[j][1]); count++)
995			{
996			rsa_num2=RSA_public_decrypt(rsa_num,buf2,buf,rsa_key[j],
997				RSA_PKCS1_PADDING);
998			if (rsa_num2 <= 0)
999				{
1000				BIO_printf(bio_err,"RSA public encrypt failure\n");
1001				ERR_print_errors(bio_err);
1002				count=1;
1003				break;
1004				}
1005			}
1006		d=Time_F(STOP);
1007		BIO_printf(bio_err,"%ld %d bit public RSA's in %.2fs\n",
1008			count,rsa_bits[j],d);
1009		rsa_results[j][1]=d/(double)count;
1010#endif
1011
1012		if (rsa_count <= 1)
1013			{
1014			/* if longer than 10s, don't do any more */
1015			for (j++; j<RSA_NUM; j++)
1016				rsa_doit[j]=0;
1017			}
1018		}
1019#endif
1020
1021	RAND_bytes(buf,20);
1022#ifndef NO_DSA
1023	for (j=0; j<DSA_NUM; j++)
1024		{
1025		unsigned int kk;
1026
1027		if (!dsa_doit[j]) continue;
1028		DSA_generate_key(dsa_key[j]);
1029/*		DSA_sign_setup(dsa_key[j],NULL); */
1030		rsa_num=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
1031			&kk,dsa_key[j]);
1032		pkey_print_message("sign","dsa",dsa_c[j][0],dsa_bits[j],
1033			DSA_SECONDS);
1034		Time_F(START);
1035		for (count=0,run=1; COND(dsa_c[j][0]); count++)
1036			{
1037			rsa_num=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
1038				&kk,dsa_key[j]);
1039			if (rsa_num <= 0)
1040				{
1041				BIO_printf(bio_err,"DSA sign failure\n");
1042				ERR_print_errors(bio_err);
1043				count=1;
1044				break;
1045				}
1046			}
1047		d=Time_F(STOP);
1048		BIO_printf(bio_err,"%ld %d bit DSA signs in %.2fs\n",
1049			count,dsa_bits[j],d);
1050		dsa_results[j][0]=d/(double)count;
1051		rsa_count=count;
1052
1053		rsa_num2=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
1054			kk,dsa_key[j]);
1055		pkey_print_message("verify","dsa",dsa_c[j][1],dsa_bits[j],
1056			DSA_SECONDS);
1057		Time_F(START);
1058		for (count=0,run=1; COND(dsa_c[j][1]); count++)
1059			{
1060			rsa_num2=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
1061				kk,dsa_key[j]);
1062			if (rsa_num2 <= 0)
1063				{
1064				BIO_printf(bio_err,"DSA verify failure\n");
1065				ERR_print_errors(bio_err);
1066				count=1;
1067				break;
1068				}
1069			}
1070		d=Time_F(STOP);
1071		BIO_printf(bio_err,"%ld %d bit DSA verify in %.2fs\n",
1072			count,dsa_bits[j],d);
1073		dsa_results[j][1]=d/(double)count;
1074
1075		if (rsa_count <= 1)
1076			{
1077			/* if longer than 10s, don't do any more */
1078			for (j++; j<DSA_NUM; j++)
1079				dsa_doit[j]=0;
1080			}
1081		}
1082#endif
1083
1084	fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_VERSION));
1085        fprintf(stdout,"%s\n",SSLeay_version(SSLEAY_BUILT_ON));
1086	printf("options:");
1087	printf("%s ",BN_options());
1088#ifndef NO_MD2
1089	printf("%s ",MD2_options());
1090#endif
1091#ifndef NO_RC4
1092	printf("%s ",RC4_options());
1093#endif
1094#ifndef NO_DES
1095	printf("%s ",des_options());
1096#endif
1097#ifndef NO_IDEA
1098	printf("%s ",idea_options());
1099#endif
1100#ifndef NO_BF
1101	printf("%s ",BF_options());
1102#endif
1103	fprintf(stdout,"\n%s\n",SSLeay_version(SSLEAY_CFLAGS));
1104
1105	if (pr_header)
1106		{
1107		fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n");
1108		fprintf(stdout,"type        ");
1109		for (j=0;  j<SIZE_NUM; j++)
1110			fprintf(stdout,"%7d bytes",lengths[j]);
1111		fprintf(stdout,"\n");
1112		}
1113
1114	for (k=0; k<ALGOR_NUM; k++)
1115		{
1116		if (!doit[k]) continue;
1117		fprintf(stdout,"%-13s",names[k]);
1118		for (j=0; j<SIZE_NUM; j++)
1119			{
1120			if (results[k][j] > 10000)
1121				fprintf(stdout," %11.2fk",results[k][j]/1e3);
1122			else
1123				fprintf(stdout," %11.2f ",results[k][j]);
1124			}
1125		fprintf(stdout,"\n");
1126		}
1127#ifndef NO_RSA
1128	j=1;
1129	for (k=0; k<RSA_NUM; k++)
1130		{
1131		if (!rsa_doit[k]) continue;
1132		if (j)
1133			{
1134			printf("%18ssign    verify    sign/s verify/s\n"," ");
1135			j=0;
1136			}
1137		fprintf(stdout,"rsa %4u bits %8.4fs %8.4fs %8.1f %8.1f",
1138			rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
1139			1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
1140		fprintf(stdout,"\n");
1141		}
1142#endif
1143#ifndef NO_DSA
1144	j=1;
1145	for (k=0; k<DSA_NUM; k++)
1146		{
1147		if (!dsa_doit[k]) continue;
1148		if (j)	{
1149			printf("%18ssign    verify    sign/s verify/s\n"," ");
1150			j=0;
1151			}
1152		fprintf(stdout,"dsa %4u bits %8.4fs %8.4fs %8.1f %8.1f",
1153			dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
1154			1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
1155		fprintf(stdout,"\n");
1156		}
1157#endif
1158	ret=0;
1159end:
1160	if (buf != NULL) Free(buf);
1161	if (buf2 != NULL) Free(buf2);
1162#ifndef NO_RSA
1163	for (i=0; i<RSA_NUM; i++)
1164		if (rsa_key[i] != NULL)
1165			RSA_free(rsa_key[i]);
1166#endif
1167#ifndef NO_DSA
1168	for (i=0; i<DSA_NUM; i++)
1169		if (dsa_key[i] != NULL)
1170			DSA_free(dsa_key[i]);
1171#endif
1172	EXIT(ret);
1173	}
1174
1175static void print_message(char *s, long num, int length)
1176	{
1177#ifdef SIGALRM
1178	BIO_printf(bio_err,"Doing %s for %ds on %d size blocks: ",s,SECONDS,length);
1179	(void)BIO_flush(bio_err);
1180	alarm(SECONDS);
1181#else
1182	BIO_printf(bio_err,"Doing %s %ld times on %d size blocks: ",s,num,length);
1183	(void)BIO_flush(bio_err);
1184#endif
1185#ifdef LINT
1186	num=num;
1187#endif
1188	}
1189
1190static void pkey_print_message(char *str, char *str2, long num, int bits,
1191	     int tm)
1192	{
1193#ifdef SIGALRM
1194	BIO_printf(bio_err,"Doing %d bit %s %s's for %ds: ",bits,str,str2,tm);
1195	(void)BIO_flush(bio_err);
1196	alarm(RSA_SECONDS);
1197#else
1198	BIO_printf(bio_err,"Doing %ld %d bit %s %s's: ",num,bits,str,str2);
1199	(void)BIO_flush(bio_err);
1200#endif
1201#ifdef LINT
1202	num=num;
1203#endif
1204	}
1205
1206