Fix WIN32 build by disabling bn* calls.
[openssl.git] / apps / speed.c
index b5b7d50b06cdf311ccf343a2053ddff2c18fd039..c99c7863c5f6f613d93a9c6c4e30a11e6c113b4d 100644 (file)
@@ -93,9 +93,6 @@
 #include <string.h>
 #include <math.h>
 #include "apps.h"
-#ifdef OPENSSL_NO_STDIO
-#define APPS_WIN16
-#endif
 #include <openssl/crypto.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
 #include "../crypto/bn/bn_lcl.h"
 
 #ifndef HAVE_FORK
-# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_NETWARE)
 #  define HAVE_FORK 0
 # else
 #  define HAVE_FORK 1
 #endif
 
 #undef BUFSIZE
-#define BUFSIZE        ((long)1024*8+1)
+#define BUFSIZE        (1024*8+1)
+#define MAX_MISALIGNMENT 63
+
 int run=0;
 
 static int mr=0;
@@ -357,11 +356,13 @@ static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
        }
 #endif /* OPENSSL_NO_ECDH */
 
+static void multiblock_speed(const EVP_CIPHER *evp_cipher);
 
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
        {
+       unsigned char *buf_malloc=NULL, *buf2_malloc=NULL;
        unsigned char *buf=NULL,*buf2=NULL;
        int mret=1;
        long count=0,save_count=0;
@@ -504,8 +505,9 @@ int MAIN(int argc, char **argv)
 #define D_PRIME_TRIAL_DIVISION                 0
 #define D_PRIME_TRIAL_DIVISION_RETRY   1
 #define D_PRIME_COPRIME                                        2
+#ifndef OPENSSL_SYS_WIN32
        long prime_c[PRIME_NUM];
-
+#endif
 #define        R_DSA_512       0
 #define        R_DSA_1024      1
 #define        R_DSA_2048      2
@@ -641,6 +643,8 @@ int MAIN(int argc, char **argv)
 #ifndef NO_FORK
        int multi=0;
 #endif
+       int multiblock=0;
+       int misalign=MAX_MISALIGNMENT+1;
 
 #ifndef TIMES
        usertime=-1;
@@ -676,17 +680,21 @@ int MAIN(int argc, char **argv)
                rsa_key[i]=NULL;
 #endif
 
-       if ((buf=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
+       if ((buf_malloc=(unsigned char *)OPENSSL_malloc(BUFSIZE+misalign)) == NULL)
                {
                BIO_printf(bio_err,"out of memory\n");
                goto end;
                }
-       if ((buf2=(unsigned char *)OPENSSL_malloc((int)BUFSIZE)) == NULL)
+       if ((buf2_malloc=(unsigned char *)OPENSSL_malloc(BUFSIZE+misalign)) == NULL)
                {
                BIO_printf(bio_err,"out of memory\n");
                goto end;
                }
 
+       misalign = 0;   /* set later and buf/buf2 are adjusted accordingly */
+       buf=buf_malloc;
+       buf2=buf2_malloc;
+
        memset(c,0,sizeof(c));
        memset(DES_iv,0,sizeof(DES_iv));
        memset(iv,0,sizeof(iv));
@@ -791,6 +799,30 @@ int MAIN(int argc, char **argv)
                        j--;    /* Otherwise, -mr gets confused with
                                   an algorithm. */
                        }
+               else if (argc > 0 && !strcmp(*argv,"-mb"))
+                       {
+                       multiblock=1;
+                       j--;
+                       }
+               else if (argc > 0 && !strcmp(*argv,"-misalign"))
+                       {
+                       argc--;
+                       argv++;
+                       if (argc == 0)
+                               {
+                               BIO_printf(bio_err,"no misalignment given\n");
+                               goto end;
+                               }
+                       misalign=atoi(argv[0]);
+                       if (misalign<0 || misalign>MAX_MISALIGNMENT)
+                               {
+                               BIO_printf(bio_err,"misalignment is outsize permitted range 0-%d\n",MAX_MISALIGNMENT);
+                               goto end;
+                               }
+                       buf=buf_malloc+misalign;
+                       buf2=buf2_malloc+misalign;
+                       j--;
+                       }
                else
 #ifndef OPENSSL_NO_MD2
                if      (strcmp(*argv,"md2") == 0) doit[D_MD2]=1;
@@ -1177,6 +1209,8 @@ int MAIN(int argc, char **argv)
                        BIO_printf(bio_err,"-evp e          use EVP e.\n");
                        BIO_printf(bio_err,"-decrypt        time decryption instead of encryption (only EVP).\n");
                        BIO_printf(bio_err,"-mr             produce machine readable output.\n");
+                       BIO_printf(bio_err,"-mb             perform multi-block benchmark (for specific ciphers)\n");
+                       BIO_printf(bio_err,"-misalign n     perform benchmark with misaligned data\n");
 #ifndef NO_FORK
                        BIO_printf(bio_err,"-multi n        run n benchmarks in parallel.\n");
 #endif
@@ -1993,6 +2027,19 @@ int MAIN(int argc, char **argv)
 
        if (doit[D_EVP])
                {
+#ifdef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+               if (multiblock && evp_cipher)
+                       {
+                       if (!(EVP_CIPHER_flags(evp_cipher)&EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK))
+                               {
+                               fprintf(stderr,"%s is not multi-block capable\n",OBJ_nid2ln(evp_cipher->nid));
+                               goto end;
+                               }
+                       multiblock_speed(evp_cipher);
+                       mret=0;
+                       goto end;
+                       }
+#endif
                for (j=0; j<SIZE_NUM; j++)
                        {
                        if (evp_cipher)
@@ -2043,7 +2090,7 @@ int MAIN(int argc, char **argv)
                        print_result(D_EVP,j,count,d);
                        }
                }
-       
+#ifndef OPENSSL_SYS_WIN32
        if (prime_doit[D_PRIME_TRIAL_DIVISION])
                {
                BIGNUM *rnd = BN_new();
@@ -2103,7 +2150,7 @@ int MAIN(int argc, char **argv)
                BN_CTX_free(ctx);
                BN_free(rnd);
                }
-
+#endif
        RAND_pseudo_bytes(buf,36);
 #ifndef OPENSSL_NO_RSA
        for (j=0; j<RSA_NUM; j++)
@@ -2645,8 +2692,8 @@ show_res:
 
 end:
        ERR_print_errors(bio_err);
-       if (buf != NULL) OPENSSL_free(buf);
-       if (buf2 != NULL) OPENSSL_free(buf2);
+       if (buf_malloc != NULL) OPENSSL_free(buf_malloc);
+       if (buf2_malloc != NULL) OPENSSL_free(buf2_malloc);
 #ifndef OPENSSL_NO_RSA
        for (i=0; i<RSA_NUM; i++)
                if (rsa_key[i] != NULL)
@@ -2968,4 +3015,109 @@ static int do_multi(int multi)
        return 1;
        }
 #endif
+
+static void multiblock_speed(const EVP_CIPHER *evp_cipher)
+       {
+       static int mblengths[]={8*1024,2*8*1024,4*8*1024,8*8*1024,8*16*1024};
+       int j,count,num=sizeof(lengths)/sizeof(lengths[0]);
+       const char *alg_name;
+       unsigned char *inp,*out,no_key[32],no_iv[16];
+       EVP_CIPHER_CTX ctx;
+       double d=0.0;
+
+       inp = OPENSSL_malloc(mblengths[num-1]);
+       out = OPENSSL_malloc(mblengths[num-1]+1024);
+
+       EVP_CIPHER_CTX_init(&ctx);
+       EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,no_key,no_iv);
+       EVP_CIPHER_CTX_ctrl(&ctx,EVP_CTRL_AEAD_SET_MAC_KEY,sizeof(no_key),no_key);
+       alg_name=OBJ_nid2ln(evp_cipher->nid);
+
+       for (j=0; j<num; j++)
+               {
+               print_message(alg_name,0,mblengths[j]);
+               Time_F(START);
+               for (count=0,run=1; run && count<0x7fffffff; count++)
+                       {
+                       unsigned char aad[13];
+                       EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
+                       size_t len = mblengths[j];
+                       int packlen;
+
+                       memset(aad,0,8);/* avoid uninitialized values */
+                       aad[8] = 23;    /* SSL3_RT_APPLICATION_DATA */
+                       aad[9] = 3;     /* version */
+                       aad[10] = 2;
+                       aad[11] = 0;    /* length */
+                       aad[12] = 0;
+                       mb_param.out = NULL;
+                       mb_param.inp = aad;
+                       mb_param.len = len;
+                       mb_param.interleave = 8;
+
+                       packlen=EVP_CIPHER_CTX_ctrl(&ctx,
+                                       EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
+                                       sizeof(mb_param),&mb_param);
+
+                       if (packlen>0)
+                               {
+                               mb_param.out = out;
+                               mb_param.inp = inp;
+                               mb_param.len = len;
+                               EVP_CIPHER_CTX_ctrl(&ctx,
+                                       EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
+                                       sizeof(mb_param),&mb_param);
+                               }
+                       else
+                               {
+                               int pad;
+
+                               RAND_bytes(out,16);
+                               len+=16;
+                               aad[11] = len>>8;
+                               aad[12] = len;
+                               pad=EVP_CIPHER_CTX_ctrl(&ctx,
+                                       EVP_CTRL_AEAD_TLS1_AAD,13,aad);
+                               EVP_Cipher(&ctx,out,inp,len+pad);
+                               }
+                       }
+               d=Time_F(STOP);
+               BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n"
+                       : "%d %s's in %.2fs\n",count,"evp",d);
+               results[D_EVP][j]=((double)count)/d*mblengths[j];
+               }
+
+       if (mr)
+               {
+               fprintf(stdout,"+H");
+               for (j=0; j<num; j++)
+                       fprintf(stdout,":%d",mblengths[j]);
+               fprintf(stdout,"\n");
+               fprintf(stdout,"+F:%d:%s",D_EVP,alg_name);
+               for (j=0; j<num; j++)
+                       fprintf(stdout,":%.2f",results[D_EVP][j]);
+               fprintf(stdout,"\n");
+               }
+       else
+               {
+               fprintf(stdout,"The 'numbers' are in 1000s of bytes per second processed.\n"); 
+               fprintf(stdout,"type                    ");
+               for (j=0;  j<num; j++)
+                       fprintf(stdout,"%7d bytes",mblengths[j]);
+               fprintf(stdout,"\n");
+               fprintf(stdout,"%-24s",alg_name);
+
+               for (j=0; j<num; j++)
+                       {
+                       if (results[D_EVP][j] > 10000)
+                               fprintf(stdout," %11.2fk",results[D_EVP][j]/1e3);
+                       else
+                               fprintf(stdout," %11.2f ",results[D_EVP][j]);
+                       }
+               fprintf(stdout,"\n");
+               }
+
+       OPENSSL_free(inp);
+       OPENSSL_free(out);
+       }
 #endif