]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/IDE/MDK5-ARM/Projects/CryptBenchmark/benchmark.c
2cccd362a33677a5f0451c5e1093fc7a601ba96b
[freertos] / FreeRTOS-Plus / Source / CyaSSL / IDE / MDK5-ARM / Projects / CryptBenchmark / benchmark.c
1 /* benchmark.c
2  *
3  * Copyright (C) 2006-2014 wolfSSL Inc.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 /* CTaoCrypt benchmark */
23
24 #ifdef HAVE_CONFIG_H
25     #include <config.h>
26 #endif
27
28 #include <cyassl/ctaocrypt/settings.h>
29
30 #include <string.h>
31 #include <stdio.h>
32
33 #include <cyassl/ctaocrypt/des3.h>
34 #include <cyassl/ctaocrypt/arc4.h>
35 #include <cyassl/ctaocrypt/hc128.h>
36 #include <cyassl/ctaocrypt/rabbit.h>
37 #include <cyassl/ctaocrypt/aes.h>
38 #include <cyassl/ctaocrypt/camellia.h>
39 #include <cyassl/ctaocrypt/md5.h>
40 #include <cyassl/ctaocrypt/sha.h>
41 #include <cyassl/ctaocrypt/sha256.h>
42 #include <cyassl/ctaocrypt/sha512.h>
43 #include <cyassl/ctaocrypt/rsa.h>
44 #include <cyassl/ctaocrypt/asn.h>
45 #include <cyassl/ctaocrypt/ripemd.h>
46 #include <cyassl/ctaocrypt/ecc.h>
47
48 #include <cyassl/ctaocrypt/dh.h>
49 #ifdef HAVE_CAVIUM
50     #include "cavium_sysdep.h"
51     #include "cavium_common.h"
52     #include "cavium_ioctl.h"
53 #endif
54
55 #if defined(CYASSL_MDK_ARM)
56     extern FILE * CyaSSL_fopen(const char *fname, const char *mode) ;
57     #define fopen CyaSSL_fopen
58 #endif
59
60 #if defined(USE_CERT_BUFFERS_1024) || defined(USE_CERT_BUFFERS_2048)
61     /* include test cert and key buffers for use with NO_FILESYSTEM */
62     #if defined(CYASSL_MDK_ARM)
63         #include "cert_data.h" /* use certs_test.c for initial data, 
64                                       so other commands can share the data. */
65     #else
66         #include <cyassl/certs_test.h>
67     #endif
68 #endif
69
70
71 #ifdef HAVE_BLAKE2
72     #include <cyassl/ctaocrypt/blake2.h>
73     void bench_blake2(void);
74 #endif
75
76 #ifdef _MSC_VER
77     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
78     #pragma warning(disable: 4996)
79 #endif
80
81 void bench_des(void);
82 void bench_arc4(void);
83 void bench_hc128(void);
84 void bench_rabbit(void);
85 void bench_aes(int);
86 void bench_aesgcm(void);
87 void bench_aesccm(void);
88 void bench_aesctr(void);
89 void bench_camellia(void);
90
91 void bench_md5(void);
92 void bench_sha(void);
93 void bench_sha256(void);
94 void bench_sha512(void);
95 void bench_ripemd(void);
96
97 void bench_rsa(void);
98 void bench_rsaKeyGen(void);
99 void bench_dh(void);
100 #ifdef HAVE_ECC
101 void bench_eccKeyGen(void);
102 void bench_eccKeyAgree(void);
103 #endif
104
105 double current_time(int);
106
107
108 #ifdef HAVE_CAVIUM
109
110 static int OpenNitroxDevice(int dma_mode,int dev_id)
111 {
112    Csp1CoreAssignment core_assign;
113    Uint32             device;
114
115    if (CspInitialize(CAVIUM_DIRECT,CAVIUM_DEV_ID))
116       return -1;
117    if (Csp1GetDevType(&device))
118       return -1;
119    if (device != NPX_DEVICE) {
120       if (ioctl(gpkpdev_hdlr[CAVIUM_DEV_ID], IOCTL_CSP1_GET_CORE_ASSIGNMENT,
121                 (Uint32 *)&core_assign)!= 0)
122          return -1;
123    }
124    CspShutdown(CAVIUM_DEV_ID);
125
126    return CspInitialize(dma_mode, dev_id);
127 }
128
129 #endif
130
131
132 /* so embedded projects can pull in tests on their own */
133 #if !defined(NO_MAIN_DRIVER)
134
135 int main(int argc, char** argv)
136
137 {
138   (void)argc;
139   (void)argv;
140 #else
141 int benchmark_test(void *args) 
142 {
143 #endif
144
145         #ifdef HAVE_CAVIUM
146     int ret = OpenNitroxDevice(CAVIUM_DIRECT, CAVIUM_DEV_ID);
147     if (ret != 0) {
148         printf("Cavium OpenNitroxDevice failed\n");
149         exit(-1);
150     }
151 #endif /* HAVE_CAVIUM */
152 #ifndef NO_AES
153     bench_aes(0);
154     bench_aes(1);
155 #endif
156 #ifdef HAVE_AESGCM
157     bench_aesgcm();
158 #endif
159
160 #ifdef CYASSL_AES_COUNTER
161     bench_aesctr();
162 #endif
163
164 #ifdef HAVE_AESCCM
165     bench_aesccm();
166 #endif
167 #ifdef HAVE_CAMELLIA
168     bench_camellia();
169 #endif
170 #ifndef NO_RC4
171     bench_arc4();
172 #endif
173 #ifdef HAVE_HC128
174     bench_hc128();
175 #endif
176 #ifndef NO_RABBIT
177     bench_rabbit();
178 #endif
179 #ifndef NO_DES3
180     bench_des();
181 #endif
182     
183     printf("\n");
184
185 #ifndef NO_MD5
186     bench_md5();
187 #endif
188 #ifndef NO_SHA
189     bench_sha();
190 #endif
191 #ifndef NO_SHA256
192     bench_sha256();
193 #endif
194 #ifdef CYASSL_SHA512
195     bench_sha512();
196 #endif
197 #ifdef CYASSL_RIPEMD
198     bench_ripemd();
199 #endif
200 #ifdef HAVE_BLAKE2
201     bench_blake2();
202 #endif
203
204     printf("\n");
205
206 #ifndef NO_RSA
207     bench_rsa();
208 #endif
209
210 #ifndef NO_DH
211     bench_dh();
212 #endif
213
214 #if defined(CYASSL_KEY_GEN) && !defined(NO_RSA)
215     bench_rsaKeyGen();
216 #endif
217
218 #ifdef HAVE_ECC 
219     bench_eccKeyGen();
220     bench_eccKeyAgree();
221 #endif
222
223     return 0;
224 }
225
226
227 #ifdef BENCH_EMBEDDED
228 enum BenchmarkBounds {
229     numBlocks  = 25, /* how many kB to test (en/de)cryption */
230     ntimes     = 1,
231     genTimes   = 5,  /* public key iterations */
232     agreeTimes = 5
233 };
234 static const char blockType[] = "kB";   /* used in printf output */
235 #else
236 enum BenchmarkBounds {
237     numBlocks  = 5,  /* how many megs to test (en/de)cryption */
238     ntimes     = 100,
239     genTimes   = 100,
240     agreeTimes = 100
241 };
242 static const char blockType[] = "megs"; /* used in printf output */
243 #endif
244
245 static const byte key[] = 
246 {
247     0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
248     0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
249     0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
250 };
251
252 static const byte iv[] = 
253 {
254     0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
255     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
256     0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
257     
258 };
259
260
261 /* use kB instead of mB for embedded benchmarking */
262 #ifdef BENCH_EMBEDDED
263 static byte plain [1024];
264 static byte cipher[1024];
265 #else
266 static byte plain [1024*1024];
267 static byte cipher[1024*1024];
268 #endif
269
270
271 #ifndef NO_AES
272 void bench_aes(int show)
273 {
274     Aes    enc;
275     double start, total, persec;
276     int    i;
277     int    ret;
278
279 #ifdef HAVE_CAVIUM
280     if (AesInitCavium(&enc, CAVIUM_DEV_ID) != 0) {
281         printf("aes init cavium failed\n");
282         return;
283     }
284 #endif
285
286     ret = AesSetKey(&enc, key, 16, iv, AES_ENCRYPTION);
287     if (ret != 0) {
288         printf("AesSetKey failed, ret = %d\n", ret);
289         return;
290     }
291     start = current_time(1);
292
293     for(i = 0; i < numBlocks; i++)
294         AesCbcEncrypt(&enc, plain, cipher, sizeof(plain));
295
296     total = current_time(0) - start;
297
298     persec = 1 / total * numBlocks;
299 #ifdef BENCH_EMBEDDED
300     /* since using kB, convert to MB/s */
301     persec = persec / 1024;
302 #endif
303
304     if (show)
305         printf("AES      %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
306                                                   blockType, total, persec);
307 #ifdef HAVE_CAVIUM
308     AesFreeCavium(&enc);
309 #endif
310 }
311 #endif
312
313
314 #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
315     static byte additional[13];
316     static byte tag[16];
317 #endif
318
319
320 #ifdef HAVE_AESGCM
321 void bench_aesgcm(void)
322 {
323     Aes    enc;
324     double start, total, persec;
325     int    i;
326
327     AesGcmSetKey(&enc, key, 16);
328     start = current_time(1);
329
330     for(i = 0; i < numBlocks; i++)
331         AesGcmEncrypt(&enc, cipher, plain, sizeof(plain), iv, 12,
332                         tag, 16, additional, 13);
333
334     total = current_time(0) - start;
335
336     persec = 1 / total * numBlocks;
337 #ifdef BENCH_EMBEDDED
338     /* since using kB, convert to MB/s */
339     persec = persec / 1024;
340 #endif
341
342     printf("AES-GCM  %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
343                                               blockType, total, persec);
344 }
345 #endif
346
347 #ifdef CYASSL_AES_COUNTER
348 void bench_aesctr(void)
349 {
350     Aes    enc;
351     double start, total, persec;
352     int    i;
353
354     AesSetKeyDirect(&enc, key, AES_BLOCK_SIZE, iv, AES_ENCRYPTION);
355     start = current_time(1);
356
357     for(i = 0; i < numBlocks; i++)
358         AesCtrEncrypt(&enc, plain, cipher, sizeof(plain));
359
360     total = current_time(0) - start;
361
362     persec = 1 / total * numBlocks;
363 #ifdef BENCH_EMBEDDED
364     /* since using kB, convert to MB/s */
365     persec = persec / 1024;
366 #endif
367
368     printf("AES-CTR  %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
369                                               blockType, total, persec);
370 }
371 #endif
372
373
374
375 #ifdef HAVE_AESCCM
376 void bench_aesccm(void)
377 {
378     Aes    enc;
379     double start, total, persec;
380     int    i;
381
382     AesCcmSetKey(&enc, key, 16);
383     start = current_time(1);
384
385     for(i = 0; i < numBlocks; i++)
386         AesCcmEncrypt(&enc, cipher, plain, sizeof(plain), iv, 12,
387                         tag, 16, additional, 13);
388
389     total = current_time(0) - start;
390
391     persec = 1 / total * numBlocks;
392 #ifdef BENCH_EMBEDDED
393     /* since using kB, convert to MB/s */
394     persec = persec / 1024;
395 #endif
396
397     printf("AES-CCM  %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
398                                               blockType, total, persec);
399 }
400 #endif
401
402
403 #ifdef HAVE_CAMELLIA
404 void bench_camellia(void)
405 {
406     Camellia cam;
407     double start, total, persec;
408     int    i, ret;
409
410     ret = CamelliaSetKey(&cam, key, 16, iv);
411     if (ret != 0) {
412         printf("CamelliaSetKey failed, ret = %d\n", ret);
413         return;
414     }
415     start = current_time(1);
416
417     for(i = 0; i < numBlocks; i++)
418         CamelliaCbcEncrypt(&cam, plain, cipher, sizeof(plain));
419
420     total = current_time(0) - start;
421
422     persec = 1 / total * numBlocks;
423 #ifdef BENCH_EMBEDDED
424     /* since using kB, convert to MB/s */
425     persec = persec / 1024;
426 #endif
427
428     printf("Camellia %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
429                                               blockType, total, persec);
430 }
431 #endif
432
433
434 #ifndef NO_DES3
435 void bench_des(void)
436 {
437     Des3   enc;
438     double start, total, persec;
439     int    i, ret;
440
441 #ifdef HAVE_CAVIUM
442     if (Des3_InitCavium(&enc, CAVIUM_DEV_ID) != 0)
443         printf("des3 init cavium failed\n");
444 #endif
445     ret = Des3_SetKey(&enc, key, iv, DES_ENCRYPTION);
446     if (ret != 0) {
447         printf("Des3_SetKey failed, ret = %d\n", ret);
448         return;
449     }
450     start = current_time(1);
451
452     for(i = 0; i < numBlocks; i++)
453         Des3_CbcEncrypt(&enc, plain, cipher, sizeof(plain));
454
455     total = current_time(0) - start;
456
457     persec = 1 / total * numBlocks;
458 #ifdef BENCH_EMBEDDED
459     /* since using kB, convert to MB/s */
460     persec = persec / 1024;
461 #endif
462
463     printf("3DES     %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
464                                               blockType, total, persec);
465 #ifdef HAVE_CAVIUM
466     Des3_FreeCavium(&enc);
467 #endif
468 }
469 #endif
470
471
472 #ifndef NO_RC4
473 void bench_arc4(void)
474 {
475     Arc4   enc;
476     double start, total, persec;
477     int    i;
478     
479 #ifdef HAVE_CAVIUM
480     if (Arc4InitCavium(&enc, CAVIUM_DEV_ID) != 0)
481         printf("arc4 init cavium failed\n");
482 #endif
483
484     Arc4SetKey(&enc, key, 16);
485     start = current_time(1);
486
487     for(i = 0; i < numBlocks; i++)
488         Arc4Process(&enc, cipher, plain, sizeof(plain));
489
490     total = current_time(0) - start;
491     persec = 1 / total * numBlocks;
492 #ifdef BENCH_EMBEDDED
493     /* since using kB, convert to MB/s */
494     persec = persec / 1024;
495 #endif
496
497     printf("ARC4     %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
498                                               blockType, total, persec);
499 #ifdef HAVE_CAVIUM
500     Arc4FreeCavium(&enc);
501 #endif
502 }
503 #endif
504
505
506 #ifdef HAVE_HC128
507 void bench_hc128(void)
508 {
509     HC128  enc;
510     double start, total, persec;
511     int    i;
512     
513     Hc128_SetKey(&enc, key, iv);
514     start = current_time(1);
515
516     for(i = 0; i < numBlocks; i++)
517         Hc128_Process(&enc, cipher, plain, sizeof(plain));
518
519     total = current_time(0) - start;
520     persec = 1 / total * numBlocks;
521 #ifdef BENCH_EMBEDDED
522     /* since using kB, convert to MB/s */
523     persec = persec / 1024;
524 #endif
525
526     printf("HC128    %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
527                                               blockType, total, persec);
528 }
529 #endif /* HAVE_HC128 */
530
531
532 #ifndef NO_RABBIT
533 void bench_rabbit(void)
534 {
535     Rabbit  enc;
536     double start, total, persec;
537     int    i;
538     
539     RabbitSetKey(&enc, key, iv);
540     start = current_time(1);
541
542     for(i = 0; i < numBlocks; i++)
543         RabbitProcess(&enc, cipher, plain, sizeof(plain));
544
545     total = current_time(0) - start;
546     persec = 1 / total * numBlocks;
547 #ifdef BENCH_EMBEDDED
548     /* since using kB, convert to MB/s */
549     persec = persec / 1024;
550 #endif
551
552     printf("RABBIT   %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
553                                               blockType, total, persec);
554 }
555 #endif /* NO_RABBIT */
556
557
558 #ifndef NO_MD5
559 void bench_md5(void)
560 {
561     Md5    hash;
562     byte   digest[MD5_DIGEST_SIZE];
563     double start, total, persec;
564     int    i;
565
566     InitMd5(&hash);
567     start = current_time(1);
568
569     for(i = 0; i < numBlocks; i++)
570         Md5Update(&hash, plain, sizeof(plain));
571    
572     Md5Final(&hash, digest);
573
574     total = current_time(0) - start;
575     persec = 1 / total * numBlocks;
576 #ifdef BENCH_EMBEDDED
577     /* since using kB, convert to MB/s */
578     persec = persec / 1024;
579 #endif
580
581     printf("MD5      %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
582                                               blockType, total, persec);
583 }
584 #endif /* NO_MD5 */
585
586
587 #ifndef NO_SHA
588 void bench_sha(void)
589 {
590     Sha    hash;
591     byte   digest[SHA_DIGEST_SIZE];
592     double start, total, persec;
593     int    i, ret;
594         
595     ret = InitSha(&hash);
596     if (ret != 0) {
597         printf("InitSha failed, ret = %d\n", ret);
598         return;
599     }
600     start = current_time(1);
601     
602     for(i = 0; i < numBlocks; i++)
603         ShaUpdate(&hash, plain, sizeof(plain));
604    
605     ShaFinal(&hash, digest);
606
607     total = current_time(0) - start;
608     persec = 1 / total * numBlocks;
609 #ifdef BENCH_EMBEDDED
610     /* since using kB, convert to MB/s */
611     persec = persec / 1024;
612 #endif
613
614     printf("SHA      %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
615                                               blockType, total, persec);
616 }
617 #endif /* NO_SHA */
618
619
620 #ifndef NO_SHA256
621 void bench_sha256(void)
622 {
623     Sha256 hash;
624     byte   digest[SHA256_DIGEST_SIZE];
625     double start, total, persec;
626     int    i, ret;
627         
628     ret = InitSha256(&hash);
629     if (ret != 0) {
630         printf("InitSha256 failed, ret = %d\n", ret);
631         return;
632     }
633     start = current_time(1);
634     
635     for(i = 0; i < numBlocks; i++) {
636         ret = Sha256Update(&hash, plain, sizeof(plain));
637         if (ret != 0) {
638             printf("Sha256Update failed, ret = %d\n", ret);
639             return;
640         }
641     }
642    
643     ret = Sha256Final(&hash, digest);
644     if (ret != 0) {
645         printf("Sha256Final failed, ret = %d\n", ret);
646         return;
647     }
648
649     total = current_time(0) - start;
650     persec = 1 / total * numBlocks;
651 #ifdef BENCH_EMBEDDED
652     /* since using kB, convert to MB/s */
653     persec = persec / 1024;
654 #endif
655
656     printf("SHA-256  %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
657                                               blockType, total, persec);
658 }
659 #endif
660
661 #ifdef CYASSL_SHA512
662 void bench_sha512(void)
663 {
664     Sha512 hash;
665     byte   digest[SHA512_DIGEST_SIZE];
666     double start, total, persec;
667     int    i, ret;
668         
669     ret = InitSha512(&hash);
670     if (ret != 0) {
671         printf("InitSha512 failed, ret = %d\n", ret);
672         return;
673     }
674     start = current_time(1);
675     
676     for(i = 0; i < numBlocks; i++) {
677         ret = Sha512Update(&hash, plain, sizeof(plain));
678         if (ret != 0) {
679             printf("Sha512Update failed, ret = %d\n", ret);
680             return;
681         }
682     }
683
684     ret = Sha512Final(&hash, digest);
685     if (ret != 0) {
686         printf("Sha512Final failed, ret = %d\n", ret);
687         return;
688     }
689
690     total = current_time(0) - start;
691     persec = 1 / total * numBlocks;
692 #ifdef BENCH_EMBEDDED
693     /* since using kB, convert to MB/s */
694     persec = persec / 1024;
695 #endif
696
697     printf("SHA-512  %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
698                                               blockType, total, persec);
699 }
700 #endif
701
702 #ifdef CYASSL_RIPEMD
703 void bench_ripemd(void)
704 {
705     RipeMd hash;
706     byte   digest[RIPEMD_DIGEST_SIZE];
707     double start, total, persec;
708     int    i;
709         
710     InitRipeMd(&hash);
711     start = current_time(1);
712     
713     for(i = 0; i < numBlocks; i++)
714         RipeMdUpdate(&hash, plain, sizeof(plain));
715    
716     RipeMdFinal(&hash, digest);
717
718     total = current_time(0) - start;
719     persec = 1 / total * numBlocks;
720 #ifdef BENCH_EMBEDDED
721     /* since using kB, convert to MB/s */
722     persec = persec / 1024;
723 #endif
724
725     printf("RIPEMD   %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
726                                               blockType, total, persec);
727 }
728 #endif
729
730
731 #ifdef HAVE_BLAKE2
732 void bench_blake2(void)
733 {
734     Blake2b b2b;
735     byte    digest[64];
736     double  start, total, persec;
737     int     i, ret;
738        
739     ret = InitBlake2b(&b2b, 64);
740     if (ret != 0) {
741         printf("InitBlake2b failed, ret = %d\n", ret);
742         return;
743     }
744     start = current_time(1);
745     
746     for(i = 0; i < numBlocks; i++) {
747         ret = Blake2bUpdate(&b2b, plain, sizeof(plain));
748         if (ret != 0) {
749             printf("Blake2bUpdate failed, ret = %d\n", ret);
750             return;
751         }
752     }
753    
754     ret = Blake2bFinal(&b2b, digest, 64);
755     if (ret != 0) {
756         printf("Blake2bFinal failed, ret = %d\n", ret);
757         return;
758     }
759
760     total = current_time(0) - start;
761     persec = 1 / total * numBlocks;
762 #ifdef BENCH_EMBEDDED
763     /* since using kB, convert to MB/s */
764     persec = persec / 1024;
765 #endif
766
767     printf("BLAKE2b  %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
768                                               blockType, total, persec);
769 }
770 #endif
771
772
773 #if !defined(NO_RSA) || !defined(NO_DH) \
774                                 || defined(CYASSL_KEYGEN) || defined(HAVE_ECC)
775 static RNG rng;
776 #endif
777
778 #ifndef NO_RSA
779
780
781 #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \
782                                                     defined(CYASSL_MDK_SHELL)
783 static char *certRSAname = "certs/rsa2048.der" ;
784 static void set_Bench_RSA_File(char * cert) { certRSAname = cert ; }   
785                                                  /* set by shell command */
786 #elif defined(CYASSL_MDK_SHELL)
787     /* nothing */
788 #else
789 static const char *certRSAname = "certs/rsa2048.der" ;
790 #endif
791
792 void bench_rsa(void)
793 {
794     int    i;
795     int    ret;
796     byte   tmp[3072];
797     size_t bytes;
798     word32 idx = 0;
799
800     byte      message[] = "Everyone gets Friday off.";
801     byte      enc[512];  /* for up to 4096 bit */
802     const int len = (int)strlen((char*)message);
803     double    start, total, each, milliEach;
804     
805     RsaKey rsaKey;
806     int    rsaKeySz = 2048; /* used in printf */
807
808 #ifdef USE_CERT_BUFFERS_1024
809     XMEMCPY(tmp, rsa_key_der_1024, sizeof_rsa_key_der_1024);
810     bytes = sizeof_rsa_key_der_1024;
811     rsaKeySz = 1024;
812 #elif defined(USE_CERT_BUFFERS_2048)
813     XMEMCPY(tmp, rsa_key_der_2048, sizeof_rsa_key_der_2048);
814     bytes = sizeof_rsa_key_der_2048;
815 #else
816     FILE*  file = fopen(certRSAname, "rb");
817
818     if (!file) {
819         printf("can't find %s, Please run from CyaSSL home dir\n", certRSAname);
820         return;
821     }
822     
823     bytes = fread(tmp, 1, sizeof(tmp), file);
824     fclose(file);
825 #endif /* USE_CERT_BUFFERS */
826
827                 
828 #ifdef HAVE_CAVIUM
829     if (RsaInitCavium(&rsaKey, CAVIUM_DEV_ID) != 0)
830         printf("RSA init cavium failed\n");
831 #endif
832     ret = InitRng(&rng);
833     if (ret < 0) {
834         printf("InitRNG failed\n");
835         return;
836     }
837     ret = InitRsaKey(&rsaKey, 0);
838     if (ret < 0) {
839         printf("InitRsaKey failed\n");
840         return;
841     }
842     ret = RsaPrivateKeyDecode(tmp, &idx, &rsaKey, (word32)bytes);
843     
844     start = current_time(1);
845
846     for (i = 0; i < ntimes; i++)
847         ret = RsaPublicEncrypt(message,len,enc,sizeof(enc), &rsaKey, &rng);
848
849     total = current_time(0) - start;
850     each  = total / ntimes;   /* per second   */
851     milliEach = each * 1000; /* milliseconds */
852
853     printf("RSA %d encryption took %6.3f milliseconds, avg over %d"
854            " iterations\n", rsaKeySz, milliEach, ntimes);
855
856     if (ret < 0) {
857         printf("Rsa Public Encrypt failed\n");
858         return;
859     }
860
861     start = current_time(1);
862
863     for (i = 0; i < ntimes; i++) {
864          byte  out[512];  /* for up to 4096 bit */
865          RsaPrivateDecrypt(enc, (word32)ret, out, sizeof(out), &rsaKey);
866     }
867
868     total = current_time(0) - start;
869     each  = total / ntimes;   /* per second   */
870     milliEach = each * 1000; /* milliseconds */
871
872     printf("RSA %d decryption took %6.3f milliseconds, avg over %d"
873            " iterations\n", rsaKeySz, milliEach, ntimes);
874
875     FreeRsaKey(&rsaKey);
876 #ifdef HAVE_CAVIUM
877     RsaFreeCavium(&rsaKey);
878 #endif
879 }
880 #endif
881
882
883 #ifndef NO_DH
884
885
886 #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \
887                                                     defined(CYASSL_MDK_SHELL)
888 static char *certDHname = "certs/dh2048.der" ;
889 void set_Bench_DH_File(char * cert) { certDHname = cert ; }    
890                                             /* set by shell command */
891 #elif defined(CYASSL_MDK_SHELL)
892     /* nothing */
893 #else
894 static const char *certDHname = "certs/dh2048.der" ;
895 #endif
896
897 void bench_dh(void)
898 {
899     int    i, ret;
900     byte   tmp[1024];
901     size_t bytes;
902     word32 idx = 0, pubSz, privSz = 0, pubSz2, privSz2, agreeSz;
903
904     byte   pub[256];    /* for 2048 bit */
905     byte   priv[256];   /* for 2048 bit */
906     byte   pub2[256];   /* for 2048 bit */
907     byte   priv2[256];  /* for 2048 bit */
908     byte   agree[256];  /* for 2048 bit */
909     
910     double start, total, each, milliEach;
911     DhKey  dhKey;
912     int    dhKeySz = 2048; /* used in printf */
913
914         
915 #ifdef USE_CERT_BUFFERS_1024
916     XMEMCPY(tmp, dh_key_der_1024, sizeof_dh_key_der_1024);
917     bytes = sizeof_dh_key_der_1024;
918     dhKeySz = 1024;
919 #elif defined(USE_CERT_BUFFERS_2048)
920     XMEMCPY(tmp, dh_key_der_2048, sizeof_dh_key_der_2048);
921     bytes = sizeof_dh_key_der_2048;
922 #else
923     FILE*  file = fopen(certDHname, "rb");
924
925     if (!file) {
926         printf("can't find %s,  Please run from CyaSSL home dir\n", certDHname);
927         return;
928     }
929
930     ret = InitRng(&rng);
931     if (ret < 0) {
932         printf("InitRNG failed\n");
933         return;
934     }
935     bytes = fread(tmp, 1, sizeof(tmp), file);
936 #endif /* USE_CERT_BUFFERS */
937
938                 
939     InitDhKey(&dhKey);
940     bytes = DhKeyDecode(tmp, &idx, &dhKey, (word32)bytes);
941     if (bytes != 0) {
942         printf("dhekydecode failed, can't benchmark\n");
943         #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
944             fclose(file);
945         #endif
946         return;
947     }
948
949     start = current_time(1);
950
951     for (i = 0; i < ntimes; i++)
952         DhGenerateKeyPair(&dhKey, &rng, priv, &privSz, pub, &pubSz);
953
954     total = current_time(0) - start;
955     each  = total / ntimes;   /* per second   */
956     milliEach = each * 1000; /* milliseconds */
957
958     printf("DH  %d key generation  %6.3f milliseconds, avg over %d"
959            " iterations\n", dhKeySz, milliEach, ntimes);
960
961     DhGenerateKeyPair(&dhKey, &rng, priv2, &privSz2, pub2, &pubSz2);
962     start = current_time(1);
963
964     for (i = 0; i < ntimes; i++)
965         DhAgree(&dhKey, agree, &agreeSz, priv, privSz, pub2, pubSz2);
966
967     total = current_time(0) - start;
968     each  = total / ntimes;   /* per second   */
969     milliEach = each * 1000; /* milliseconds */
970
971     printf("DH  %d key agreement   %6.3f milliseconds, avg over %d"
972            " iterations\n", dhKeySz, milliEach, ntimes);
973
974 #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
975     fclose(file);
976 #endif
977     FreeDhKey(&dhKey);
978 }
979 #endif
980
981 #if defined(CYASSL_KEY_GEN) && !defined(NO_RSA)
982 void bench_rsaKeyGen(void)
983 {
984     RsaKey genKey;
985     double start, total, each, milliEach;
986     int    i;
987   
988     /* 1024 bit */ 
989     start = current_time(1);
990
991     for(i = 0; i < genTimes; i++) {
992         InitRsaKey(&genKey, 0); 
993         MakeRsaKey(&genKey, 1024, 65537, &rng);
994         FreeRsaKey(&genKey);
995     }
996
997     total = current_time(0) - start;
998     each  = total / genTimes;  /* per second  */
999     milliEach = each * 1000;   /* millisconds */
1000     printf("\n");
1001     printf("RSA 1024 key generation  %6.3f milliseconds, avg over %d"
1002            " iterations\n", milliEach, genTimes);
1003
1004     /* 2048 bit */
1005     start = current_time(1);
1006
1007     for(i = 0; i < genTimes; i++) {
1008         InitRsaKey(&genKey, 0); 
1009         MakeRsaKey(&genKey, 2048, 65537, &rng);
1010         FreeRsaKey(&genKey);
1011     }
1012
1013     total = current_time(0) - start;
1014     each  = total / genTimes;  /* per second  */
1015     milliEach = each * 1000;   /* millisconds */
1016     printf("RSA 2048 key generation  %6.3f milliseconds, avg over %d"
1017            " iterations\n", milliEach, genTimes);
1018 }
1019 #endif /* CYASSL_KEY_GEN */
1020
1021 #ifdef HAVE_ECC 
1022 void bench_eccKeyGen(void)
1023 {
1024     ecc_key genKey;
1025     double start, total, each, milliEach;
1026     int    i, ret;
1027   
1028     ret = InitRng(&rng);
1029     if (ret < 0) {
1030         printf("InitRNG failed\n");
1031         return;
1032     }
1033     /* 256 bit */ 
1034     start = current_time(1);
1035
1036     for(i = 0; i < genTimes; i++) {
1037         ecc_make_key(&rng, 32, &genKey);
1038         ecc_free(&genKey);
1039     }
1040
1041     total = current_time(0) - start;
1042     each  = total / genTimes;  /* per second  */
1043     milliEach = each * 1000;   /* millisconds */
1044     printf("\n");
1045     printf("ECC  256 key generation  %6.3f milliseconds, avg over %d"
1046            " iterations\n", milliEach, genTimes);
1047 }
1048
1049
1050 void bench_eccKeyAgree(void)
1051 {
1052     ecc_key genKey, genKey2;
1053     double start, total, each, milliEach;
1054     int    i, ret;
1055     byte   shared[1024];
1056     byte   sig[1024];
1057     byte   digest[32];
1058     word32 x = 0;
1059  
1060     ecc_init(&genKey);
1061     ecc_init(&genKey2);
1062
1063     ret = InitRng(&rng);
1064     if (ret < 0) {
1065         printf("InitRNG failed\n");
1066         return;
1067     }
1068
1069     ret = ecc_make_key(&rng, 32, &genKey);
1070     if (ret != 0) {
1071         printf("ecc_make_key failed\n");
1072         return;
1073     }
1074     ret = ecc_make_key(&rng, 32, &genKey2);
1075     if (ret != 0) {
1076         printf("ecc_make_key failed\n");
1077         return;
1078     }
1079
1080     /* 256 bit */ 
1081     start = current_time(1);
1082
1083     for(i = 0; i < agreeTimes; i++) {
1084         x = sizeof(shared);
1085         ret = ecc_shared_secret(&genKey, &genKey2, shared, &x);
1086         if (ret != 0) {
1087             printf("ecc_shared_secret failed\n");
1088             return; 
1089         }
1090     }
1091
1092     total = current_time(0) - start;
1093     each  = total / agreeTimes;  /* per second  */
1094     milliEach = each * 1000;   /* millisconds */
1095     printf("EC-DHE   key agreement   %6.3f milliseconds, avg over %d"
1096            " iterations\n", milliEach, agreeTimes);
1097
1098     /* make dummy digest */
1099     for (i = 0; i < (int)sizeof(digest); i++)
1100         digest[i] = (byte)i;
1101
1102
1103     start = current_time(1);
1104
1105     for(i = 0; i < agreeTimes; i++) {
1106         x = sizeof(sig);
1107         ret = ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &genKey);
1108         if (ret != 0) {
1109             printf("ecc_sign_hash failed\n");
1110             return; 
1111         }
1112     }
1113
1114     total = current_time(0) - start;
1115     each  = total / agreeTimes;  /* per second  */
1116     milliEach = each * 1000;   /* millisconds */
1117     printf("EC-DSA   sign   time     %6.3f milliseconds, avg over %d"
1118            " iterations\n", milliEach, agreeTimes);
1119
1120     start = current_time(1);
1121
1122     for(i = 0; i < agreeTimes; i++) {
1123         int verify = 0;
1124         ret = ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &genKey);
1125         if (ret != 0) {
1126             printf("ecc_verify_hash failed\n");
1127             return; 
1128         }
1129     }
1130
1131     total = current_time(0) - start;
1132     each  = total / agreeTimes;  /* per second  */
1133     milliEach = each * 1000;     /* millisconds */
1134     printf("EC-DSA   verify time     %6.3f milliseconds, avg over %d"
1135            " iterations\n", milliEach, agreeTimes);
1136
1137     ecc_free(&genKey2);
1138     ecc_free(&genKey);
1139 }
1140 #endif /* HAVE_ECC */
1141
1142
1143 #ifdef _WIN32
1144
1145     #define WIN32_LEAN_AND_MEAN
1146     #include <windows.h>
1147
1148     double current_time(int reset)
1149     {
1150         static int init = 0;
1151         static LARGE_INTEGER freq;
1152     
1153         LARGE_INTEGER count;
1154
1155         (void)reset;
1156
1157         if (!init) {
1158             QueryPerformanceFrequency(&freq);
1159             init = 1;
1160         }
1161
1162         QueryPerformanceCounter(&count);
1163
1164         return (double)count.QuadPart / freq.QuadPart;
1165     }
1166
1167 #elif defined MICROCHIP_PIC32
1168     #if defined(CYASSL_MICROCHIP_PIC32MZ)
1169         #define CLOCK 8000000.0
1170     #else
1171         #include <peripheral/timer.h>
1172         #define CLOCK 4000000.0
1173     #endif
1174
1175     double current_time(int reset)
1176     {
1177         unsigned int ns;
1178
1179         if (reset) {
1180             WriteCoreTimer(0);
1181         }
1182
1183         /* get timer in ns */
1184         ns = ReadCoreTimer();
1185
1186         /* return seconds as a double */
1187         return ( ns / CLOCK * 2.0);
1188     }
1189
1190 #elif defined CYASSL_MDK_ARM
1191
1192     extern double current_time(int reset) ;
1193
1194 #elif defined FREERTOS
1195
1196     double current_time(int reset)
1197     {
1198         (void) reset;
1199
1200         portTickType tickCount;
1201
1202         /* tick count == ms, if configTICK_RATE_HZ is set to 1000 */
1203         tickCount = xTaskGetTickCount();
1204         return (double)tickCount / 1000;
1205     }
1206
1207 #else
1208
1209     #include <sys/time.h>
1210
1211     double current_time(int reset)
1212     {
1213         struct timeval tv;
1214
1215         (void)reset;
1216
1217         gettimeofday(&tv, 0);
1218
1219         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
1220     }
1221
1222 #endif /* _WIN32 */