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