If the source has already been succesfully queried, do not try to open it
[openssl.git] / apps / speed.c
index 7166606da7c8a32574889b39d1484aa6851870ee..6ce4a0e914e52083df30f0d1644127f0680705ff 100644 (file)
 #include <openssl/crypto.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
 
-#if !defined(MSDOS) && (!defined(VMS) || defined(__DECC))
-#define TIMES
+#if defined(__FreeBSD__)
+# define USE_TOD
+#elif !defined(MSDOS) && (!defined(VMS) || defined(__DECC))
+# define TIMES
+#endif
+#if !defined(_UNICOS) && !defined(__OpenBSD__) && !defined(sgi) && !defined(__FreeBSD__) && !(defined(__bsdi) || defined(__bsdi__)) && !defined(_AIX) && !defined(MPE) && !defined(__NetBSD__) /* FIXME */
+# define TIMEB
 #endif
 
 #ifndef _IRIX
-#include <time.h>
+# include <time.h>
 #endif
 #ifdef TIMES
-#include <sys/types.h>
-#include <sys/times.h>
+# include <sys/types.h>
+# include <sys/times.h>
+#endif
+#ifdef USE_TOD
+# include <sys/time.h>
+# include <sys/resource.h>
 #endif
 
 /* Depending on the VMS version, the tms structure is perhaps defined.
 #undef TIMES
 #endif
 
+#ifdef TIMEB
 #include <sys/timeb.h>
+#endif
+
+#if !defined(TIMES) && !defined(TIMEB) && !defined(USE_TOD)
+#error "It seems neither struct tms nor struct timeb is supported in this platform!"
+#endif
 
 #if defined(sun) || defined(__ultrix)
 #define _POSIX_SOURCE
 #ifndef NO_MDC2
 #include <openssl/mdc2.h>
 #endif
+#ifndef NO_MD4
+#include <openssl/md4.h>
+#endif
 #ifndef NO_MD5
 #include <openssl/md5.h>
 #endif
 int run=0;
 
 static double Time_F(int s, int usertime);
-static void print_message(char *s,long num,int length);
+static void print_message(const char *s,long num,int length);
 static void pkey_print_message(char *str,char *str2,long num,int bits,int sec);
 #ifdef SIGALRM
 #if defined(__STDC__) || defined(sgi) || defined(_AIX)
@@ -203,7 +224,49 @@ static SIGRETTYPE sig_done(int sig)
 static double Time_F(int s, int usertime)
        {
        double ret;
-#ifdef TIMES
+
+#ifdef USE_TOD
+       if(usertime)
+           {
+               static struct rusage tstart,tend;
+
+               if (s == START)
+                       {
+                       getrusage(RUSAGE_SELF,&tstart);
+                       return(0);
+                       }
+               else
+                       {
+                       long i;
+
+                       getrusage(RUSAGE_SELF,&tend);
+                       i=(long)tend.ru_utime.tv_usec-(long)tstart.ru_utime.tv_usec;
+                       ret=((double)(tend.ru_utime.tv_sec-tstart.ru_utime.tv_sec))
+                         +((double)i)/1000000.0;
+                       return((ret < 0.001)?0.001:ret);
+                       }
+               }
+       else
+               {
+               static struct timeval tstart,tend;
+               long i;
+
+               if (s == START)
+                       {
+                       gettimeofday(&tstart,NULL);
+                       return(0);
+                       }
+               else
+                       {
+                       gettimeofday(&tend,NULL);
+                       i=(long)tend.tv_usec-(long)tstart.tv_usec;
+                       ret=((double)(tend.tv_sec-tstart.tv_sec))+((double)i)/1000000.0;
+                       return((ret < 0.001)?0.001:ret);
+                       }
+               }
+#else  /* ndef USE_TOD */
+               
+# ifdef TIMES
        if (usertime)
                {
                static struct tms tstart,tend;
@@ -220,8 +283,11 @@ static double Time_F(int s, int usertime)
                        return((ret < 1e-3)?1e-3:ret);
                        }
                }
+# endif /* times() */
+# if defined(TIMES) && defined(TIMEB)
        else
-#endif /* times() */
+# endif
+# ifdef TIMEB
                {
                static struct timeb tstart,tend;
                long i;
@@ -239,27 +305,35 @@ static double Time_F(int s, int usertime)
                        return((ret < 0.001)?0.001:ret);
                        }
                }
+# endif
+#endif
        }
 
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
        {
+       ENGINE *e;
        unsigned char *buf=NULL,*buf2=NULL;
        int mret=1;
-#define ALGOR_NUM      14
+#define ALGOR_NUM      16
 #define SIZE_NUM       5
 #define RSA_NUM                4
 #define DSA_NUM                3
-       long count,rsa_count;
+       long count,rsa_count,save_count=0;
        int i,j,k;
-       unsigned rsa_num,rsa_num2;
+#ifndef NO_RSA
+       unsigned rsa_num;
+#endif
 #ifndef NO_MD2
        unsigned char md2[MD2_DIGEST_LENGTH];
 #endif
 #ifndef NO_MDC2
        unsigned char mdc2[MDC2_DIGEST_LENGTH];
 #endif
+#ifndef NO_MD4
+       unsigned char md4[MD4_DIGEST_LENGTH];
+#endif
 #ifndef NO_MD5
        unsigned char md5[MD5_DIGEST_LENGTH];
        unsigned char hmac[MD5_DIGEST_LENGTH];
@@ -301,23 +375,25 @@ int MAIN(int argc, char **argv)
 #endif
 #define        D_MD2           0
 #define        D_MDC2          1
-#define        D_MD5           2
-#define        D_HMAC          3
-#define        D_SHA1          4
-#define D_RMD160       5
-#define        D_RC4           6
-#define        D_CBC_DES       7
-#define        D_EDE3_DES      8
-#define        D_CBC_IDEA      9
-#define        D_CBC_RC2       10
-#define        D_CBC_RC5       11
-#define        D_CBC_BF        12
-#define        D_CBC_CAST      13
+#define        D_MD4           2
+#define        D_MD5           3
+#define        D_HMAC          4
+#define        D_SHA1          5
+#define D_RMD160       6
+#define        D_RC4           7
+#define        D_CBC_DES       8
+#define        D_EDE3_DES      9
+#define        D_CBC_IDEA      10
+#define        D_CBC_RC2       11
+#define        D_CBC_RC5       12
+#define        D_CBC_BF        13
+#define        D_CBC_CAST      14
+#define D_EVP          15
        double d,results[ALGOR_NUM][SIZE_NUM];
        static int lengths[SIZE_NUM]={8,64,256,1024,8*1024};
        long c[ALGOR_NUM][SIZE_NUM];
-       static char *names[ALGOR_NUM]={
-               "md2","mdc2","md5","hmac(md5)","sha1","rmd160","rc4",
+       static const char *names[ALGOR_NUM]={
+               "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
                "des cbc","des ede3","idea cbc",
                "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc"};
 #define        R_DSA_512       0
@@ -349,6 +425,7 @@ int MAIN(int argc, char **argv)
        int doit[ALGOR_NUM];
        int pr_header=0;
        int usertime=1;
+       const EVP_CIPHER *evp=NULL;
 
 #ifndef TIMES
        usertime=-1;
@@ -401,6 +478,54 @@ int MAIN(int argc, char **argv)
                {
                if      ((argc > 0) && (strcmp(*argv,"-elapsed") == 0))
                        usertime = 0;
+               else if ((argc > 0) && (strcmp(*argv,"-evp") == 0))
+                       {
+                       argc--;
+                       argv++;
+                       if(argc == 0)
+                               {
+                               BIO_printf(bio_err,"no EVP given\n");
+                               goto end;
+                               }
+                       evp=EVP_get_cipherbyname(*argv);
+                       if(!evp)
+                               {
+                               BIO_printf(bio_err,"%s is an unknown cipher\n",*argv);
+                               goto end;
+                               }
+                       doit[D_EVP]=1;
+                       }
+               else
+               if      ((argc > 0) && (strcmp(*argv,"-engine") == 0))
+                       {
+                       argc--;
+                       argv++;
+                       if(argc == 0)
+                               {
+                               BIO_printf(bio_err,"no engine given\n");
+                               goto end;
+                               }
+                       if((e = ENGINE_by_id(*argv)) == NULL)
+                               {
+                               BIO_printf(bio_err,"invalid engine \"%s\"\n",
+                                       *argv);
+                               goto end;
+                               }
+                       if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+                               {
+                               BIO_printf(bio_err,"can't use that engine\n");
+                               goto end;
+                               }
+                       BIO_printf(bio_err,"engine \"%s\" set.\n", *argv);
+                       /* Free our "structural" reference. */
+                       ENGINE_free(e);
+                       /* It will be increased again further down.  We just
+                          don't want speed to confuse an engine with an
+                          algorithm, especially when none is given (which
+                          means all of them should be run) */
+                       j--;
+                       }
+               else
 #ifndef NO_MD2
                if      (strcmp(*argv,"md2") == 0) doit[D_MD2]=1;
                else
@@ -409,6 +534,10 @@ int MAIN(int argc, char **argv)
                        if (strcmp(*argv,"mdc2") == 0) doit[D_MDC2]=1;
                else
 #endif
+#ifndef NO_MD4
+                       if (strcmp(*argv,"md4") == 0) doit[D_MD4]=1;
+               else
+#endif
 #ifndef NO_MD5
                        if (strcmp(*argv,"md5") == 0) doit[D_MD5]=1;
                else
@@ -441,10 +570,10 @@ int MAIN(int argc, char **argv)
                else
 #endif
 #ifndef NO_RSA
-#ifdef RSAref
+#if 0 /* was: #ifdef RSAref */
                        if (strcmp(*argv,"rsaref") == 0) 
                        {
-                       RSA_set_default_method(RSA_PKCS1_RSAref());
+                       RSA_set_default_openssl_method(RSA_PKCS1_RSAref());
                        j--;
                        }
                else
@@ -452,7 +581,7 @@ int MAIN(int argc, char **argv)
 #ifndef RSA_NULL
                        if (strcmp(*argv,"openssl") == 0) 
                        {
-                       RSA_set_default_method(RSA_PKCS1_SSLeay());
+                       RSA_set_default_openssl_method(RSA_PKCS1_SSLeay());
                        j--;
                        }
                else
@@ -520,8 +649,34 @@ int MAIN(int argc, char **argv)
                else
 #endif
                        {
-                       BIO_printf(bio_err,"bad option or value, pick one of\n");
-                       BIO_printf(bio_err,"md2      mdc2       md5      hmac      sha1    rmd160\n");
+                       BIO_printf(bio_err,"Error: bad option or value\n");
+                       BIO_printf(bio_err,"\n");
+                       BIO_printf(bio_err,"Available values:\n");
+#ifndef NO_MD2
+                       BIO_printf(bio_err,"md2      ");
+#endif
+#ifndef NO_MDC2
+                       BIO_printf(bio_err,"mdc2     ");
+#endif
+#ifndef NO_MD4
+                       BIO_printf(bio_err,"md4      ");
+#endif
+#ifndef NO_MD5
+                       BIO_printf(bio_err,"md5      ");
+#ifndef NO_HMAC
+                       BIO_printf(bio_err,"hmac     ");
+#endif
+#endif
+#ifndef NO_SHA1
+                       BIO_printf(bio_err,"sha1     ");
+#endif
+#ifndef NO_RIPEMD160
+                       BIO_printf(bio_err,"rmd160");
+#endif
+#if !defined(NO_MD2) || !defined(NO_MDC2) || !defined(NO_MD4) || !defined(NO_MD5) || !defined(NO_SHA1) || !defined(NO_RIPEMD160)
+                       BIO_printf(bio_err,"\n");
+#endif
+
 #ifndef NO_IDEA
                        BIO_printf(bio_err,"idea-cbc ");
 #endif
@@ -534,24 +689,49 @@ int MAIN(int argc, char **argv)
 #ifndef NO_BF
                        BIO_printf(bio_err,"bf-cbc");
 #endif
-#if !defined(NO_IDEA) && !defined(NO_RC2) && !defined(NO_BF) && !defined(NO_RC5)
+#if !defined(NO_IDEA) || !defined(NO_RC2) || !defined(NO_BF) || !defined(NO_RC5)
                        BIO_printf(bio_err,"\n");
 #endif
+
                        BIO_printf(bio_err,"des-cbc  des-ede3 ");
 #ifndef NO_RC4
                        BIO_printf(bio_err,"rc4");
 #endif
+                       BIO_printf(bio_err,"\n");
+
 #ifndef NO_RSA
-                       BIO_printf(bio_err,"\nrsa512   rsa1024  rsa2048  rsa4096\n");
+                       BIO_printf(bio_err,"rsa512   rsa1024  rsa2048  rsa4096\n");
 #endif
+
 #ifndef NO_DSA
-                       BIO_printf(bio_err,"\ndsa512   dsa1024  dsa2048\n");
+                       BIO_printf(bio_err,"dsa512   dsa1024  dsa2048\n");
+#endif
+
+#ifndef NO_IDEA
+                       BIO_printf(bio_err,"idea     ");
+#endif
+#ifndef NO_RC2
+                       BIO_printf(bio_err,"rc2      ");
 #endif
-                       BIO_printf(bio_err,"idea     rc2      des      rsa    blowfish\n");
+#ifndef NO_DES
+                       BIO_printf(bio_err,"des      ");
+#endif
+#ifndef NO_RSA
+                       BIO_printf(bio_err,"rsa      ");
+#endif
+#ifndef NO_BF
+                       BIO_printf(bio_err,"blowfish");
+#endif
+#if !defined(NO_IDEA) || !defined(NO_RC2) || !defined(NO_DES) || !defined(NO_RSA) || !defined(NO_BF)
                        BIO_printf(bio_err,"\n");
-                       BIO_printf(bio_err,"Available options:\n");
+#endif
+
                        BIO_printf(bio_err,"\n");
+                       BIO_printf(bio_err,"Available options:\n");
+#ifdef TIMES
                        BIO_printf(bio_err,"-elapsed        measure time in real time instead of CPU user time.\n");
+#endif
+                       BIO_printf(bio_err,"-engine e       use engine e, possibly a hardware device.\n");
                        goto end;
                        }
                argc--;
@@ -562,7 +742,10 @@ int MAIN(int argc, char **argv)
        if (j == 0)
                {
                for (i=0; i<ALGOR_NUM; i++)
-                       doit[i]=1;
+                       {
+                       if (i != D_EVP)
+                               doit[i]=1;
+                       }
                for (i=0; i<RSA_NUM; i++)
                        rsa_doit[i]=1;
                for (i=0; i<DSA_NUM; i++)
@@ -582,7 +765,7 @@ int MAIN(int argc, char **argv)
 #ifndef NO_RSA
        for (i=0; i<RSA_NUM; i++)
                {
-               unsigned char *p;
+               const unsigned char *p;
 
                p=rsa_data[i];
                rsa_key[i]=d2i_RSAPrivateKey(NULL,&p,rsa_data_length[i]);
@@ -647,8 +830,10 @@ int MAIN(int argc, char **argv)
                                &(sch[0]),DES_ENCRYPT);
                d=Time_F(STOP,usertime);
                } while (d <3);
+       save_count=count;
        c[D_MD2][0]=count/10;
        c[D_MDC2][0]=count/10;
+       c[D_MD4][0]=count;
        c[D_MD5][0]=count;
        c[D_HMAC][0]=count;
        c[D_SHA1][0]=count;
@@ -666,6 +851,7 @@ int MAIN(int argc, char **argv)
                {
                c[D_MD2][i]=c[D_MD2][0]*4*lengths[0]/lengths[i];
                c[D_MDC2][i]=c[D_MDC2][0]*4*lengths[0]/lengths[i];
+               c[D_MD4][i]=c[D_MD4][0]*4*lengths[0]/lengths[i];
                c[D_MD5][i]=c[D_MD5][0]*4*lengths[0]/lengths[i];
                c[D_HMAC][i]=c[D_HMAC][0]*4*lengths[0]/lengths[i];
                c[D_SHA1][i]=c[D_SHA1][0]*4*lengths[0]/lengths[i];
@@ -769,6 +955,23 @@ int MAIN(int argc, char **argv)
                }
 #endif
 
+#ifndef NO_MD4
+       if (doit[D_MD4])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_MD4],c[D_MD4][j],lengths[j]);
+                       Time_F(START,usertime);
+                       for (count=0,run=1; COND(c[D_MD4][j]); count++)
+                               MD4(&(buf[0]),(unsigned long)lengths[j],&(md4[0]));
+                       d=Time_F(STOP,usertime);
+                       BIO_printf(bio_err,"%ld %s's in %.2fs\n",
+                               count,names[D_MD4],d);
+                       results[D_MD4][j]=((double)count)/d*lengths[j];
+                       }
+               }
+#endif
+
 #ifndef NO_MD5
        if (doit[D_MD5])
                {
@@ -984,6 +1187,28 @@ int MAIN(int argc, char **argv)
                }
 #endif
 
+       if (doit[D_EVP])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       EVP_CIPHER_CTX ctx;
+                       int outl;
+
+                       names[D_EVP]=OBJ_nid2ln(evp->nid);
+                       print_message(names[D_EVP],save_count,
+                                                 lengths[j]);
+                       EVP_EncryptInit(&ctx,evp,key16,iv);
+                       Time_F(START,usertime);
+                       for (count=0,run=1; COND(save_count*4*lengths[0]/lengths[j]); count++)
+                           EVP_EncryptUpdate(&ctx,buf,&outl,buf,lengths[j]);
+                       EVP_EncryptFinal(&ctx,buf,&outl);
+                       d=Time_F(STOP,usertime);
+                       BIO_printf(bio_err,"%ld %s's in %.2fs\n",
+                                          count,names[D_EVP],d);
+                       results[D_EVP][j]=((double)count)/d*lengths[j];
+                       }
+               }
+
        RAND_pseudo_bytes(buf,36);
 #ifndef NO_RSA
        for (j=0; j<RSA_NUM; j++)
@@ -991,49 +1216,73 @@ int MAIN(int argc, char **argv)
                int ret;
                if (!rsa_doit[j]) continue;
                ret=RSA_sign(NID_md5_sha1, buf,36, buf2, &rsa_num, rsa_key[j]);
-               pkey_print_message("private","rsa",rsa_c[j][0],rsa_bits[j],
-                       RSA_SECONDS);
-/*             RSA_blinding_on(rsa_key[j],NULL); */
-               Time_F(START,usertime);
-               for (count=0,run=1; COND(rsa_c[j][0]); count++)
+               if (ret == 0)
+                       {
+                       BIO_printf(bio_err,"RSA sign failure.  No RSA sign will be done.\n");
+                       ERR_print_errors(bio_err);
+                       rsa_count=1;
+                       }
+               else
                        {
-                       ret=RSA_sign(NID_md5_sha1, buf,36, buf2, &rsa_num,
-                                                                rsa_key[j]);
-                       if (ret <= 0)
+                       pkey_print_message("private","rsa",
+                               rsa_c[j][0],rsa_bits[j],
+                               RSA_SECONDS);
+/*                     RSA_blinding_on(rsa_key[j],NULL); */
+                       Time_F(START,usertime);
+                       for (count=0,run=1; COND(rsa_c[j][0]); count++)
                                {
-                               BIO_printf(bio_err,"RSA private encrypt failure\n");
-                               ERR_print_errors(bio_err);
-                               count=1;
-                               break;
+                               ret=RSA_sign(NID_md5_sha1, buf,36, buf2,
+                                       &rsa_num, rsa_key[j]);
+                               if (ret == 0)
+                                       {
+                                       BIO_printf(bio_err,
+                                               "RSA sign failure\n");
+                                       ERR_print_errors(bio_err);
+                                       count=1;
+                                       break;
+                                       }
                                }
+                       d=Time_F(STOP,usertime);
+                       BIO_printf(bio_err,
+                               "%ld %d bit private RSA's in %.2fs\n",
+                               count,rsa_bits[j],d);
+                       rsa_results[j][0]=d/(double)count;
+                       rsa_count=count;
                        }
-               d=Time_F(STOP,usertime);
-               BIO_printf(bio_err,"%ld %d bit private RSA's in %.2fs\n",
-                       count,rsa_bits[j],d);
-               rsa_results[j][0]=d/(double)count;
-               rsa_count=count;
 
 #if 1
                ret=RSA_verify(NID_md5_sha1, buf,36, buf2, rsa_num, rsa_key[j]);
-               pkey_print_message("public","rsa",rsa_c[j][1],rsa_bits[j],
-                       RSA_SECONDS);
-               Time_F(START,usertime);
-               for (count=0,run=1; COND(rsa_c[j][1]); count++)
+               if (ret <= 0)
+                       {
+                       BIO_printf(bio_err,"RSA verify failure.  No RSA verify will be done.\n");
+                       ERR_print_errors(bio_err);
+                       dsa_doit[j] = 0;
+                       }
+               else
                        {
-                       ret=RSA_verify(NID_md5_sha1, buf,36, buf2, rsa_num,
-                                                               rsa_key[j]);
-                       if (ret <= 0)
+                       pkey_print_message("public","rsa",
+                               rsa_c[j][1],rsa_bits[j],
+                               RSA_SECONDS);
+                       Time_F(START,usertime);
+                       for (count=0,run=1; COND(rsa_c[j][1]); count++)
                                {
-                               BIO_printf(bio_err,"RSA verify failure\n");
-                               ERR_print_errors(bio_err);
-                               count=1;
-                               break;
+                               ret=RSA_verify(NID_md5_sha1, buf,36, buf2,
+                                       rsa_num, rsa_key[j]);
+                               if (ret == 0)
+                                       {
+                                       BIO_printf(bio_err,
+                                               "RSA verify failure\n");
+                                       ERR_print_errors(bio_err);
+                                       count=1;
+                                       break;
+                                       }
                                }
+                       d=Time_F(STOP,usertime);
+                       BIO_printf(bio_err,
+                               "%ld %d bit public RSA's in %.2fs\n",
+                               count,rsa_bits[j],d);
+                       rsa_results[j][1]=d/(double)count;
                        }
-               d=Time_F(STOP,usertime);
-               BIO_printf(bio_err,"%ld %d bit public RSA's in %.2fs\n",
-                       count,rsa_bits[j],d);
-               rsa_results[j][1]=d/(double)count;
 #endif
 
                if (rsa_count <= 1)
@@ -1055,54 +1304,77 @@ int MAIN(int argc, char **argv)
        for (j=0; j<DSA_NUM; j++)
                {
                unsigned int kk;
+               int ret;
 
                if (!dsa_doit[j]) continue;
                DSA_generate_key(dsa_key[j]);
 /*             DSA_sign_setup(dsa_key[j],NULL); */
-               rsa_num=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
+               ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
                        &kk,dsa_key[j]);
-               pkey_print_message("sign","dsa",dsa_c[j][0],dsa_bits[j],
-                       DSA_SECONDS);
-               Time_F(START,usertime);
-               for (count=0,run=1; COND(dsa_c[j][0]); count++)
+               if (ret == 0)
                        {
-                       rsa_num=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
-                               &kk,dsa_key[j]);
-                       if (rsa_num == 0)
+                       BIO_printf(bio_err,"DSA sign failure.  No DSA sign will be done.\n");
+                       ERR_print_errors(bio_err);
+                       rsa_count=1;
+                       }
+               else
+                       {
+                       pkey_print_message("sign","dsa",
+                               dsa_c[j][0],dsa_bits[j],
+                               DSA_SECONDS);
+                       Time_F(START,usertime);
+                       for (count=0,run=1; COND(dsa_c[j][0]); count++)
                                {
-                               BIO_printf(bio_err,"DSA sign failure\n");
-                               ERR_print_errors(bio_err);
-                               count=1;
-                               break;
+                               ret=DSA_sign(EVP_PKEY_DSA,buf,20,buf2,
+                                       &kk,dsa_key[j]);
+                               if (ret == 0)
+                                       {
+                                       BIO_printf(bio_err,
+                                               "DSA sign failure\n");
+                                       ERR_print_errors(bio_err);
+                                       count=1;
+                                       break;
+                                       }
                                }
+                       d=Time_F(STOP,usertime);
+                       BIO_printf(bio_err,"%ld %d bit DSA signs in %.2fs\n",
+                               count,dsa_bits[j],d);
+                       dsa_results[j][0]=d/(double)count;
+                       rsa_count=count;
                        }
-               d=Time_F(STOP,usertime);
-               BIO_printf(bio_err,"%ld %d bit DSA signs in %.2fs\n",
-                       count,dsa_bits[j],d);
-               dsa_results[j][0]=d/(double)count;
-               rsa_count=count;
 
-               rsa_num2=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
+               ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
                        kk,dsa_key[j]);
-               pkey_print_message("verify","dsa",dsa_c[j][1],dsa_bits[j],
-                       DSA_SECONDS);
-               Time_F(START,usertime);
-               for (count=0,run=1; COND(dsa_c[j][1]); count++)
+               if (ret <= 0)
                        {
-                       rsa_num2=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
-                               kk,dsa_key[j]);
-                       if (rsa_num2 == 0)
+                       BIO_printf(bio_err,"DSA verify failure.  No DSA verify will be done.\n");
+                       ERR_print_errors(bio_err);
+                       dsa_doit[j] = 0;
+                       }
+               else
+                       {
+                       pkey_print_message("verify","dsa",
+                               dsa_c[j][1],dsa_bits[j],
+                               DSA_SECONDS);
+                       Time_F(START,usertime);
+                       for (count=0,run=1; COND(dsa_c[j][1]); count++)
                                {
-                               BIO_printf(bio_err,"DSA verify failure\n");
-                               ERR_print_errors(bio_err);
-                               count=1;
-                               break;
+                               ret=DSA_verify(EVP_PKEY_DSA,buf,20,buf2,
+                                       kk,dsa_key[j]);
+                               if (ret <= 0)
+                                       {
+                                       BIO_printf(bio_err,
+                                               "DSA verify failure\n");
+                                       ERR_print_errors(bio_err);
+                                       count=1;
+                                       break;
+                                       }
                                }
+                       d=Time_F(STOP,usertime);
+                       BIO_printf(bio_err,"%ld %d bit DSA verify in %.2fs\n",
+                               count,dsa_bits[j],d);
+                       dsa_results[j][1]=d/(double)count;
                        }
-               d=Time_F(STOP,usertime);
-               BIO_printf(bio_err,"%ld %d bit DSA verify in %.2fs\n",
-                       count,dsa_bits[j],d);
-               dsa_results[j][1]=d/(double)count;
 
                if (rsa_count <= 1)
                        {
@@ -1190,6 +1462,7 @@ int MAIN(int argc, char **argv)
 #endif
        mret=0;
 end:
+       ERR_print_errors(bio_err);
        if (buf != NULL) OPENSSL_free(buf);
        if (buf2 != NULL) OPENSSL_free(buf2);
 #ifndef NO_RSA
@@ -1205,7 +1478,7 @@ end:
        EXIT(mret);
        }
 
-static void print_message(char *s, long num, int length)
+static void print_message(const char *s, long num, int length)
        {
 #ifdef SIGALRM
        BIO_printf(bio_err,"Doing %s for %ds on %d size blocks: ",s,SECONDS,length);