1 /* benchmark.c
2  *
3  * Copyright (C) 2006-2021 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL.
6  *
7  * wolfSSL 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  * wolfSSL 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-1335, USA
20  */
21 
22 
23 /* wolfCrypt benchmark */
24 
25 
26 #ifdef HAVE_CONFIG_H
27     #include <config.h>
28 #endif
29 
30 #ifndef WOLFSSL_USER_SETTINGS
31     #include <wolfssl/options.h>
32 #endif
33 #include <wolfssl/wolfcrypt/settings.h>
34 #include <wolfssl/version.h>
35 #include <wolfssl/wolfcrypt/wc_port.h>
36 #include <wolfssl/wolfcrypt/ecc.h>
37 
38 /* Macro to disable benchmark */
39 #ifndef NO_CRYPT_BENCHMARK
40 
41 /* only for stack size check */
42 #ifdef HAVE_STACK_SIZE
43     #include <wolfssl/ssl.h>
44     #include <wolfssl/test.h>
45 #endif
46 
47 #ifdef USE_FLAT_BENCHMARK_H
48     #include "benchmark.h"
49 #else
50     #include "wolfcrypt/benchmark/benchmark.h"
51 #endif
52 
53 /* printf mappings */
54 #ifdef FREESCALE_MQX
55     #include <mqx.h>
56     /* see wc_port.h for fio.h and nio.h includes */
57 #elif defined(FREESCALE_KSDK_1_3)
58     #include "fsl_debug_console.h"
59     #include "fsl_os_abstraction.h"
60 
61     #undef printf
62     #define printf PRINTF
63 #elif defined(WOLFSSL_DEOS)
64     #include <deos.h>
65     #include <printx.h>
66     #undef printf
67     #define printf printx
68 #elif defined(MICRIUM)
69     #if (OS_VERSION < 50000)
70         #include <bsp_ser.h>
71         void BSP_Ser_Printf (CPU_CHAR* format, ...);
72         #undef printf
73         #define printf BSP_Ser_Printf
74     #endif
75 #elif defined(WOLFSSL_ZEPHYR)
76     #include <stdio.h>
77     #define BENCH_EMBEDDED
78     #define printf printfk
printfk(const char * fmt,...)79     static int printfk(const char *fmt, ...)
80     {
81         int ret;
82         char line[150];
83         va_list ap;
84 
85         va_start(ap, fmt);
86 
87         ret = vsnprintf(line, sizeof(line), fmt, ap);
88         line[sizeof(line)-1] = '\0';
89         printk("%s", line);
90 
91         va_end(ap);
92 
93         return ret;
94     }
95 
96 #elif defined(WOLFSSL_TELIT_M2MB)
97     #include <stdarg.h>
98     #include <stdio.h>
99     #include <string.h>
100     #include "m2m_log.h" /* for M2M_LOG_INFO - not standard API */
101     /* remap printf */
102     #undef printf
103     #define printf M2M_LOG_INFO
104     /* OS requires occasional sleep() */
105     #ifndef TEST_SLEEP_MS
106         #define TEST_SLEEP_MS 50
107     #endif
108     #define TEST_SLEEP() m2mb_os_taskSleep(M2MB_OS_MS2TICKS(TEST_SLEEP_MS))
109     /* don't use file system for these tests, since ./certs dir isn't loaded */
110     #undef  NO_FILESYSTEM
111     #define NO_FILESYSTEM
112 
113 /* ANDROID_V454 (for android studio) displays information in a textview
114  * and redirects printf to the textview output instead of using
115  * __android_log_print() */
116 #elif defined(ANDROID) && !defined(ANDROID_V454)
117     #ifdef XMALLOC_USER
118         #include <stdlib.h>  /* we're using malloc / free direct here */
119     #endif
120     #ifndef STRING_USER
121         #include <stdio.h>
122     #endif
123     #include <android/log.h>
124 
125     #define printf(...)       \
126                       __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__)
127     #define fprintf(fp, ...)  \
128                       __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__)
129 
130 #else
131     #if defined(XMALLOC_USER) || defined(FREESCALE_MQX)
132         /* MQX classic needs for EXIT_FAILURE */
133         #include <stdlib.h>  /* we're using malloc / free direct here */
134     #endif
135 
136     #ifndef STRING_USER
137         #include <string.h>
138         #include <stdio.h>
139     #endif
140 
141     /* enable way for customer to override test/bench printf */
142     #ifdef XPRINTF
143         #undef  printf
144         #define printf XPRINTF
145     #elif defined(NETOS)
146         #undef printf
147         #define printf dc_log_printf
148     #endif
149 #endif
150 
151 #include <wolfssl/wolfcrypt/memory.h>
152 #include <wolfssl/wolfcrypt/random.h>
153 #include <wolfssl/wolfcrypt/des3.h>
154 #include <wolfssl/wolfcrypt/arc4.h>
155 #include <wolfssl/wolfcrypt/hc128.h>
156 #include <wolfssl/wolfcrypt/rabbit.h>
157 #include <wolfssl/wolfcrypt/chacha.h>
158 #include <wolfssl/wolfcrypt/chacha20_poly1305.h>
159 #include <wolfssl/wolfcrypt/aes.h>
160 #include <wolfssl/wolfcrypt/poly1305.h>
161 #include <wolfssl/wolfcrypt/camellia.h>
162 #include <wolfssl/wolfcrypt/md5.h>
163 #include <wolfssl/wolfcrypt/sha.h>
164 #include <wolfssl/wolfcrypt/sha256.h>
165 #include <wolfssl/wolfcrypt/sha512.h>
166 #include <wolfssl/wolfcrypt/sha3.h>
167 #include <wolfssl/wolfcrypt/rsa.h>
168 #include <wolfssl/wolfcrypt/asn.h>
169 #include <wolfssl/wolfcrypt/ripemd.h>
170 #include <wolfssl/wolfcrypt/cmac.h>
171 #ifndef NO_HMAC
172     #include <wolfssl/wolfcrypt/hmac.h>
173 #endif
174 #ifndef NO_PWDBASED
175     #include <wolfssl/wolfcrypt/pwdbased.h>
176 #endif
177 #ifdef HAVE_ECC
178     #include <wolfssl/wolfcrypt/ecc.h>
179 #endif
180 #ifdef HAVE_IDEA
181     #include <wolfssl/wolfcrypt/idea.h>
182 #endif
183 #ifdef HAVE_CURVE25519
184     #include <wolfssl/wolfcrypt/curve25519.h>
185 #endif
186 #ifdef HAVE_ED25519
187     #include <wolfssl/wolfcrypt/ed25519.h>
188 #endif
189 #ifdef HAVE_CURVE448
190     #include <wolfssl/wolfcrypt/curve448.h>
191 #endif
192 #ifdef HAVE_ED448
193     #include <wolfssl/wolfcrypt/ed448.h>
194 #endif
195 #ifdef WOLFCRYPT_HAVE_ECCSI
196     #include <wolfssl/wolfcrypt/eccsi.h>
197 #endif
198 #ifdef WOLFCRYPT_HAVE_SAKKE
199     #include <wolfssl/wolfcrypt/sakke.h>
200 #endif
201 #ifdef HAVE_LIBOQS
202     #include <oqs/kem.h>
203 #endif
204 #ifdef HAVE_PQC
205     #include <wolfssl/wolfcrypt/falcon.h>
206 #endif
207 
208 #include <wolfssl/wolfcrypt/dh.h>
209 #include <wolfssl/wolfcrypt/random.h>
210 #include <wolfssl/wolfcrypt/error-crypt.h>
211 #include <wolfssl/wolfcrypt/types.h>
212 
213 #ifdef WOLF_CRYPTO_CB
214     #include <wolfssl/wolfcrypt/cryptocb.h>
215     #ifdef HAVE_INTEL_QA_SYNC
216         #include <wolfssl/wolfcrypt/port/intel/quickassist_sync.h>
217     #endif
218     #ifdef HAVE_CAVIUM_OCTEON_SYNC
219         #include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
220     #endif
221     #ifdef HAVE_RENESAS_SYNC
222         #include <wolfssl/wolfcrypt/port/renesas/renesas_sync.h>
223     #endif
224 #endif
225 
226 #ifdef WOLFSSL_ASYNC_CRYPT
227     #include <wolfssl/wolfcrypt/async.h>
228 #endif
229 
230 #ifdef HAVE_FIPS
231     #include <wolfssl/wolfcrypt/fips_test.h>
232 
myFipsCb(int ok,int err,const char * hash)233     static void myFipsCb(int ok, int err, const char* hash)
234     {
235         printf("in my Fips callback, ok = %d, err = %d\n", ok, err);
236         printf("message = %s\n", wc_GetErrorString(err));
237         printf("hash = %s\n", hash);
238 
239         if (err == IN_CORE_FIPS_E) {
240             printf("In core integrity hash check failure, copy above hash\n");
241             printf("into verifyCore[] in fips_test.c and rebuild\n");
242         }
243     }
244 #endif
245 
246 #ifdef WOLFSSL_STATIC_MEMORY
247     static WOLFSSL_HEAP_HINT* HEAP_HINT;
248 #else
249     #define HEAP_HINT NULL
250 #endif /* WOLFSSL_STATIC_MEMORY */
251 
252 #ifndef EXIT_FAILURE
253 #define EXIT_FAILURE 1
254 #endif
255 
256 /* optional macro to add sleep between tests */
257 #ifndef TEST_SLEEP
258     /* stub the sleep macro */
259     #define TEST_SLEEP()
260 #endif
261 
262 #define TEST_STRING    "Everyone gets Friday off."
263 #define TEST_STRING_SZ 25
264 
265 
266 /* Bit values for each algorithm that is able to be benchmarked.
267  * Common grouping of algorithms also.
268  * Each algorithm has a unique value for its type e.g. cipher.
269  */
270 /* Cipher algorithms. */
271 #define BENCH_AES_CBC            0x00000001
272 #define BENCH_AES_GCM            0x00000002
273 #define BENCH_AES_ECB            0x00000004
274 #define BENCH_AES_XTS            0x00000008
275 #define BENCH_AES_CTR            0x00000010
276 #define BENCH_AES_CCM            0x00000020
277 #define BENCH_CAMELLIA           0x00000100
278 #define BENCH_ARC4               0x00000200
279 #define BENCH_HC128              0x00000400
280 #define BENCH_RABBIT             0x00000800
281 #define BENCH_CHACHA20           0x00001000
282 #define BENCH_CHACHA20_POLY1305  0x00002000
283 #define BENCH_DES                0x00004000
284 #define BENCH_IDEA               0x00008000
285 #define BENCH_AES_CFB            0x00010000
286 #define BENCH_AES_OFB            0x00020000
287 /* Digest algorithms. */
288 #define BENCH_MD5                0x00000001
289 #define BENCH_POLY1305           0x00000002
290 #define BENCH_SHA                0x00000004
291 #define BENCH_SHA224             0x00000010
292 #define BENCH_SHA256             0x00000020
293 #define BENCH_SHA384             0x00000040
294 #define BENCH_SHA512             0x00000080
295 #define BENCH_SHA2               (BENCH_SHA224 | BENCH_SHA256 | \
296                                   BENCH_SHA384 | BENCH_SHA512)
297 #define BENCH_SHA3_224           0x00000100
298 #define BENCH_SHA3_256           0x00000200
299 #define BENCH_SHA3_384           0x00000400
300 #define BENCH_SHA3_512           0x00000800
301 #define BENCH_SHA3               (BENCH_SHA3_224 | BENCH_SHA3_256 | \
302                                   BENCH_SHA3_384 | BENCH_SHA3_512)
303 #define BENCH_RIPEMD             0x00001000
304 #define BENCH_BLAKE2B            0x00002000
305 #define BENCH_BLAKE2S            0x00004000
306 
307 /* MAC algorithms. */
308 #define BENCH_CMAC               0x00000001
309 #define BENCH_HMAC_MD5           0x00000002
310 #define BENCH_HMAC_SHA           0x00000004
311 #define BENCH_HMAC_SHA224        0x00000010
312 #define BENCH_HMAC_SHA256        0x00000020
313 #define BENCH_HMAC_SHA384        0x00000040
314 #define BENCH_HMAC_SHA512        0x00000080
315 #define BENCH_HMAC               (BENCH_HMAC_MD5    | BENCH_HMAC_SHA    | \
316                                   BENCH_HMAC_SHA224 | BENCH_HMAC_SHA256 | \
317                                   BENCH_HMAC_SHA384 | BENCH_HMAC_SHA512)
318 #define BENCH_PBKDF2             0x00000100
319 
320 /* Asymmetric algorithms. */
321 #define BENCH_RSA_KEYGEN         0x00000001
322 #define BENCH_RSA                0x00000002
323 #define BENCH_RSA_SZ             0x00000004
324 #define BENCH_DH                 0x00000010
325 #define BENCH_ECC_MAKEKEY        0x00001000
326 #define BENCH_ECC                0x00002000
327 #define BENCH_ECC_ENCRYPT        0x00004000
328 #define BENCH_ECC_ALL            0x00008000
329 #define BENCH_CURVE25519_KEYGEN  0x00010000
330 #define BENCH_CURVE25519_KA      0x00020000
331 #define BENCH_ED25519_KEYGEN     0x00040000
332 #define BENCH_ED25519_SIGN       0x00080000
333 #define BENCH_CURVE448_KEYGEN    0x00100000
334 #define BENCH_CURVE448_KA        0x00200000
335 #define BENCH_ED448_KEYGEN       0x00400000
336 #define BENCH_ED448_SIGN         0x00800000
337 #define BENCH_ECC_P256           0x01000000
338 #define BENCH_ECC_P384           0x02000000
339 #define BENCH_ECCSI_KEYGEN       0x00000020
340 #define BENCH_ECCSI_PAIRGEN      0x00000040
341 #define BENCH_ECCSI_VALIDATE     0x00000080
342 #define BENCH_ECCSI              0x00000400
343 #define BENCH_SAKKE_KEYGEN       0x10000000
344 #define BENCH_SAKKE_RSKGEN       0x20000000
345 #define BENCH_SAKKE_VALIDATE     0x40000000
346 #define BENCH_SAKKE              0x80000000
347 
348 /* Post-Quantum Asymmetric algorithms. */
349 #define BENCH_FALCON_LEVEL1_SIGN     0x00000001
350 #define BENCH_FALCON_LEVEL5_SIGN     0x00000002
351 #define BENCH_KYBER_LEVEL1_KEYGEN    0x00000004
352 #define BENCH_KYBER_LEVEL1_ENCAP     0x00000008
353 #define BENCH_KYBER_LEVEL3_KEYGEN    0x00000010
354 #define BENCH_KYBER_LEVEL3_ENCAP     0x00000020
355 #define BENCH_KYBER_LEVEL5_KEYGEN    0x00000040
356 #define BENCH_KYBER_LEVEL5_ENCAP     0x00000080
357 #define BENCH_KYBER90S_LEVEL1_KEYGEN 0x00000100
358 #define BENCH_KYBER90S_LEVEL1_ENCAP  0x00000200
359 #define BENCH_KYBER90S_LEVEL3_KEYGEN 0x00000400
360 #define BENCH_KYBER90S_LEVEL3_ENCAP  0x00000800
361 #define BENCH_KYBER90S_LEVEL5_KEYGEN 0x00001000
362 #define BENCH_KYBER90S_LEVEL5_ENCAP  0x00002000
363 #define BENCH_SABER_LEVEL1_KEYGEN    0x00004000
364 #define BENCH_SABER_LEVEL1_ENCAP     0x00008000
365 #define BENCH_SABER_LEVEL3_KEYGEN    0x00010000
366 #define BENCH_SABER_LEVEL3_ENCAP     0x00020000
367 #define BENCH_SABER_LEVEL5_KEYGEN    0x00040000
368 #define BENCH_SABER_LEVEL5_ENCAP     0x00080000
369 #define BENCH_NTRUHPS_LEVEL1_KEYGEN  0x00100000
370 #define BENCH_NTRUHPS_LEVEL1_ENCAP   0x00200000
371 #define BENCH_NTRUHPS_LEVEL3_KEYGEN  0x00400000
372 #define BENCH_NTRUHPS_LEVEL3_ENCAP   0x00800000
373 #define BENCH_NTRUHPS_LEVEL5_KEYGEN  0x01000000
374 #define BENCH_NTRUHPS_LEVEL5_ENCAP   0x02000000
375 #define BENCH_NTRUHRSS_LEVEL3_KEYGEN 0x04000000
376 #define BENCH_NTRUHRSS_LEVEL3_ENCAP  0x08000000
377 
378 /* Other */
379 #define BENCH_RNG                0x00000001
380 #define BENCH_SCRYPT             0x00000002
381 
382 
383 /* Benchmark all compiled in algorithms.
384  * When 1, ignore other benchmark algorithm values.
385  *      0, only benchmark algorithm values set.
386  */
387 static int bench_all = 1;
388 /* Cipher algorithms to benchmark. */
389 static int bench_cipher_algs = 0;
390 /* Digest algorithms to benchmark. */
391 static int bench_digest_algs = 0;
392 /* MAC algorithms to benchmark. */
393 static int bench_mac_algs = 0;
394 /* Asymmetric algorithms to benchmark. */
395 static int bench_asym_algs = 0;
396 /* Post-Quantum Asymmetric algorithms to benchmark. */
397 static int bench_pq_asym_algs = 0;
398 /* Other cryptographic algorithms to benchmark. */
399 static int bench_other_algs = 0;
400 
401 #if !defined(WOLFSSL_BENCHMARK_ALL) && !defined(NO_MAIN_DRIVER)
402 
403 /* The mapping of command line option to bit values. */
404 typedef struct bench_alg {
405     /* Command line option string. */
406     const char* str;
407     /* Bit values to set. */
408     word32 val;
409 } bench_alg;
410 
411 #ifndef MAIN_NO_ARGS
412 /* All recognized cipher algorithm choosing command line options. */
413 static const bench_alg bench_cipher_opt[] = {
414     { "-cipher",             0xffffffff              },
415 #ifdef HAVE_AES_CBC
416     { "-aes-cbc",            BENCH_AES_CBC           },
417 #endif
418 #ifdef HAVE_AESGCM
419     { "-aes-gcm",            BENCH_AES_GCM           },
420 #endif
421 #ifdef WOLFSSL_AES_DIRECT
422     { "-aes-ecb",            BENCH_AES_ECB           },
423 #endif
424 #ifdef WOLFSSL_AES_XTS
425     { "-aes-xts",            BENCH_AES_XTS           },
426 #endif
427 #ifdef WOLFSSL_AES_CFB
428     { "-aes-cfb",            BENCH_AES_CFB           },
429 #endif
430 #ifdef WOLFSSL_AES_OFB
431     { "-aes-ofb",            BENCH_AES_OFB           },
432 #endif
433 #ifdef WOLFSSL_AES_COUNTER
434     { "-aes-ctr",            BENCH_AES_CTR           },
435 #endif
436 #ifdef HAVE_AESCCM
437     { "-aes-ccm",            BENCH_AES_CCM           },
438 #endif
439 #ifdef HAVE_CAMELLIA
440     { "-camellia",           BENCH_CAMELLIA          },
441 #endif
442 #ifndef NO_RC4
443     { "-arc4",               BENCH_ARC4              },
444 #endif
445 #ifdef HAVE_HC128
446     { "-hc128",              BENCH_HC128             },
447 #endif
448 #ifndef NO_RABBIT
449     { "-rabbit",             BENCH_RABBIT            },
450 #endif
451 #ifdef HAVE_CHACHA
452     { "-chacha20",           BENCH_CHACHA20          },
453 #endif
454 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
455     { "-chacha20-poly1305",  BENCH_CHACHA20_POLY1305 },
456 #endif
457 #ifndef NO_DES3
458     { "-des",                BENCH_DES               },
459 #endif
460 #ifdef HAVE_IDEA
461     { "-idea",               BENCH_IDEA              },
462 #endif
463     { NULL, 0 }
464 };
465 
466 /* All recognized digest algorithm choosing command line options. */
467 static const bench_alg bench_digest_opt[] = {
468     { "-digest",             0xffffffff              },
469 #ifndef NO_MD5
470     { "-md5",                BENCH_MD5               },
471 #endif
472 #ifdef HAVE_POLY1305
473     { "-poly1305",           BENCH_POLY1305          },
474 #endif
475 #ifndef NO_SHA
476     { "-sha",                BENCH_SHA               },
477 #endif
478 #if defined(WOLFSSL_SHA224) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) \
479                                                    || defined(WOLFSSL_SHA512)
480     { "-sha2",               BENCH_SHA2              },
481 #endif
482 #ifdef WOLFSSL_SHA224
483     { "-sha224",             BENCH_SHA224            },
484 #endif
485 #ifndef NO_SHA256
486     { "-sha256",             BENCH_SHA256            },
487 #endif
488 #ifdef WOLFSSL_SHA384
489     { "-sha384",             BENCH_SHA384            },
490 #endif
491 #ifdef WOLFSSL_SHA512
492     { "-sha512",             BENCH_SHA512            },
493 #endif
494 #ifdef WOLFSSL_SHA3
495     { "-sha3",               BENCH_SHA3              },
496     #ifndef WOLFSSL_NOSHA3_224
497     { "-sha3-224",           BENCH_SHA3_224          },
498     #endif
499     #ifndef WOLFSSL_NOSHA3_256
500     { "-sha3-256",           BENCH_SHA3_256          },
501     #endif
502     #ifndef WOLFSSL_NOSHA3_384
503     { "-sha3-384",           BENCH_SHA3_384          },
504     #endif
505     #ifndef WOLFSSL_NOSHA3_512
506     { "-sha3-512",           BENCH_SHA3_512          },
507     #endif
508 #endif
509 #ifdef WOLFSSL_RIPEMD
510     { "-ripemd",             BENCH_RIPEMD            },
511 #endif
512 #ifdef HAVE_BLAKE2
513     { "-blake2b",            BENCH_BLAKE2B           },
514 #endif
515 #ifdef HAVE_BLAKE2S
516     { "-blake2s",            BENCH_BLAKE2S           },
517 #endif
518     { NULL, 0 }
519 };
520 
521 /* All recognized MAC algorithm choosing command line options. */
522 static const bench_alg bench_mac_opt[] = {
523     { "-mac",                0xffffffff              },
524 #ifdef WOLFSSL_CMAC
525     { "-cmac",               BENCH_CMAC              },
526 #endif
527 #ifndef NO_HMAC
528     { "-hmac",               BENCH_HMAC              },
529     #ifndef NO_MD5
530     { "-hmac-md5",           BENCH_HMAC_MD5          },
531     #endif
532     #ifndef NO_SHA
533     { "-hmac-sha",           BENCH_HMAC_SHA          },
534     #endif
535     #ifdef WOLFSSL_SHA224
536     { "-hmac-sha224",        BENCH_HMAC_SHA224       },
537     #endif
538     #ifndef NO_SHA256
539     { "-hmac-sha256",        BENCH_HMAC_SHA256       },
540     #endif
541     #ifdef WOLFSSL_SHA384
542     { "-hmac-sha384",        BENCH_HMAC_SHA384       },
543     #endif
544     #ifdef WOLFSSL_SHA512
545     { "-hmac-sha512",        BENCH_HMAC_SHA512       },
546     #endif
547     #ifndef NO_PWDBASED
548     { "-pbkdf2",             BENCH_PBKDF2            },
549     #endif
550 #endif
551     { NULL, 0 }
552 };
553 
554 /* All recognized asymmetric algorithm choosing command line options. */
555 static const bench_alg bench_asym_opt[] = {
556     { "-asym",               0xffffffff              },
557 #ifndef NO_RSA
558     #ifdef WOLFSSL_KEY_GEN
559     { "-rsa-kg",             BENCH_RSA_KEYGEN        },
560     #endif
561     { "-rsa",                BENCH_RSA               },
562     { "-rsa-sz",             BENCH_RSA_SZ            },
563 #endif
564 #ifndef NO_DH
565     { "-dh",                 BENCH_DH                },
566 #endif
567 #ifdef HAVE_ECC
568     { "-ecc-kg",             BENCH_ECC_MAKEKEY       },
569     { "-ecc",                BENCH_ECC               },
570     #ifdef HAVE_ECC_ENCRYPT
571     { "-ecc-enc",            BENCH_ECC_ENCRYPT       },
572     #endif
573     { "-ecc-all",            BENCH_ECC_ALL           },
574 #endif
575 #ifdef HAVE_CURVE25519
576     { "-curve25519-kg",      BENCH_CURVE25519_KEYGEN },
577     #ifdef HAVE_CURVE25519_SHARED_SECRET
578     { "-x25519",             BENCH_CURVE25519_KA     },
579     #endif
580 #endif
581 #ifdef HAVE_ED25519
582     { "-ed25519-kg",         BENCH_ED25519_KEYGEN    },
583     { "-ed25519",            BENCH_ED25519_SIGN      },
584 #endif
585 #ifdef HAVE_CURVE448
586     { "-curve448-kg",        BENCH_CURVE448_KEYGEN   },
587     #ifdef HAVE_CURVE448_SHARED_SECRET
588     { "-x448",               BENCH_CURVE448_KA       },
589     #endif
590 #endif
591 #ifdef HAVE_ED448
592     { "-ed448-kg",           BENCH_ED448_KEYGEN      },
593     { "-ed448",              BENCH_ED448_SIGN        },
594 #endif
595 #ifdef WOLFCRYPT_HAVE_ECCSI
596     { "-eccsi-kg",           BENCH_ECCSI_KEYGEN      },
597     { "-eccsi-pair",         BENCH_ECCSI_PAIRGEN     },
598     { "-eccsi-val",          BENCH_ECCSI_VALIDATE    },
599     { "-eccsi",              BENCH_ECCSI             },
600 #endif
601 #ifdef WOLFCRYPT_HAVE_SAKKE
602     { "-sakke-kg",           BENCH_SAKKE_KEYGEN      },
603     { "-sakke-rsk",          BENCH_SAKKE_RSKGEN      },
604     { "-sakke-val",          BENCH_SAKKE_VALIDATE    },
605     { "-sakke",              BENCH_SAKKE             },
606 #endif
607     { NULL, 0 }
608 };
609 
610 /* The post-quantum-specific mapping of command line option to bit values and
611  * OQS name. */
612 typedef struct bench_pq_alg {
613     /* Command line option string. */
614     const char* str;
615     /* Bit values to set. */
616     word32 val;
617     const char* pqc_name;
618 } bench_pq_alg;
619 
620 /* All recognized post-quantum asymmetric algorithm choosing command line
621  * options. */
622 static const bench_pq_alg bench_pq_asym_opt[] = {
623     { "-pq",                 0xffffffff, NULL},
624 #ifdef HAVE_LIBOQS
625     { "-falcon_level1",      BENCH_FALCON_LEVEL1_SIGN,
626       OQS_SIG_alg_falcon_512 },
627     { "-falcon_level5",      BENCH_FALCON_LEVEL5_SIGN,
628       OQS_SIG_alg_falcon_1024 },
629     { "-kyber_level1-kg",    BENCH_KYBER_LEVEL1_KEYGEN,
630       OQS_KEM_alg_kyber_512 },
631     { "-kyber_level1-ed",       BENCH_KYBER_LEVEL1_ENCAP,
632       OQS_KEM_alg_kyber_512 },
633     { "-kyber_level3-kg",    BENCH_KYBER_LEVEL3_KEYGEN,
634       OQS_KEM_alg_kyber_768 },
635     { "-kyber_level3-ed",       BENCH_KYBER_LEVEL3_ENCAP,
636       OQS_KEM_alg_kyber_768 },
637     { "-kyber_level5-kg",    BENCH_KYBER_LEVEL5_KEYGEN,
638       OQS_KEM_alg_kyber_1024 },
639     { "-kyber_level5-ed",       BENCH_KYBER_LEVEL5_ENCAP,
640       OQS_KEM_alg_kyber_1024 },
641     { "-kyber90s_level1-kg", BENCH_KYBER90S_LEVEL1_KEYGEN,
642       OQS_KEM_alg_kyber_512_90s },
643     { "-kyber90s_level1-ed",    BENCH_KYBER90S_LEVEL1_ENCAP,
644       OQS_KEM_alg_kyber_512_90s },
645     { "-kyber90s_level3-kg", BENCH_KYBER90S_LEVEL3_KEYGEN,
646       OQS_KEM_alg_kyber_768_90s },
647     { "-kyber90s_level3-ed",    BENCH_KYBER90S_LEVEL3_ENCAP,
648       OQS_KEM_alg_kyber_768_90s },
649     { "-kyber90s_level5-kg", BENCH_KYBER90S_LEVEL5_KEYGEN,
650       OQS_KEM_alg_kyber_1024_90s},
651     { "-kyber90s_level5-ed",    BENCH_KYBER90S_LEVEL5_ENCAP,
652       OQS_KEM_alg_kyber_1024_90s },
653     { "-saber_level1-kg",    BENCH_SABER_LEVEL1_KEYGEN,
654       OQS_KEM_alg_saber_lightsaber },
655     { "-saber_level1-ed",       BENCH_SABER_LEVEL1_ENCAP,
656       OQS_KEM_alg_saber_lightsaber },
657     { "-saber_level3-kg",    BENCH_SABER_LEVEL3_KEYGEN,
658       OQS_KEM_alg_saber_saber },
659     { "-saber_level3-ed",       BENCH_SABER_LEVEL3_ENCAP,
660       OQS_KEM_alg_saber_saber },
661     { "-saber_level5-kg",    BENCH_SABER_LEVEL5_KEYGEN,
662       OQS_KEM_alg_saber_firesaber },
663     { "-saber_level5-ed",       BENCH_SABER_LEVEL5_ENCAP,
664       OQS_KEM_alg_saber_firesaber },
665     { "-ntruHPS_level1-kg",  BENCH_NTRUHPS_LEVEL1_KEYGEN,
666       OQS_KEM_alg_ntru_hps2048509 },
667     { "-ntruHPS_level1-ed",     BENCH_NTRUHPS_LEVEL1_ENCAP,
668       OQS_KEM_alg_ntru_hps2048509 },
669     { "-ntruHPS_level3-kg",  BENCH_NTRUHPS_LEVEL3_KEYGEN,
670       OQS_KEM_alg_ntru_hps2048677 },
671     { "-ntruHPS_level3-ed",     BENCH_NTRUHPS_LEVEL3_ENCAP,
672       OQS_KEM_alg_ntru_hps2048677 },
673     { "-ntruHPS_level5-kg",  BENCH_NTRUHPS_LEVEL5_KEYGEN,
674       OQS_KEM_alg_ntru_hps4096821 },
675     { "-ntruHPS_level5-ed",     BENCH_NTRUHPS_LEVEL5_ENCAP,
676       OQS_KEM_alg_ntru_hps4096821 },
677     { "-ntruHRSS_level3-kg", BENCH_NTRUHRSS_LEVEL3_KEYGEN,
678       OQS_KEM_alg_ntru_hrss701 },
679     { "-ntruHRSS_level3-ed",    BENCH_NTRUHRSS_LEVEL3_ENCAP,
680       OQS_KEM_alg_ntru_hrss701 },
681 #endif
682     { NULL, 0, NULL }
683 };
684 
685 /* All recognized other cryptographic algorithm choosing command line options.
686  */
687 static const bench_alg bench_other_opt[] = {
688     { "-other",              0xffffffff              },
689 #ifndef WC_NO_RNG
690     { "-rng",                BENCH_RNG               },
691 #endif
692 #ifdef HAVE_SCRYPT
693     { "-scrypt",             BENCH_SCRYPT            },
694 #endif
695     { NULL, 0}
696 };
697 #endif /* MAIN_NO_ARGS */
698 
699 #endif /* !WOLFSSL_BENCHMARK_ALL && !NO_MAIN_DRIVER */
700 
701 
702 #ifdef HAVE_WNR
703     const char* wnrConfigFile = "wnr-example.conf";
704 #endif
705 
706 #if defined(WOLFSSL_MDK_ARM)
707     extern XFILE wolfSSL_fopen(const char *fname, const char *mode);
708     #define fopen wolfSSL_fopen
709 #endif
710 
711 static int lng_index = 0;
712 
713 #ifndef NO_MAIN_DRIVER
714 #ifndef MAIN_NO_ARGS
715 static const char* bench_Usage_msg1[][17] = {
716     /* 0 English  */
717     {   "-? <num>    Help, print this usage\n            0: English, 1: Japanese\n",
718         "-csv        Print terminal output in csv format\n",
719         "-base10     Display bytes as power of 10 (eg 1 kB = 1000 Bytes)\n",
720         "-no_aad     No additional authentication data passed.\n",
721         "-dgst_full  Full digest operation performed.\n",
722         "-rsa_sign   Measure RSA sign/verify instead of encrypt/decrypt.\n",
723         "<keySz> -rsa-sz\n            Measure RSA <key size> performance.\n",
724         "-ffhdhe2048 Measure DH using FFDHE 2048-bit parameters.\n",
725         "-ffhdhe3072 Measure DH using FFDHE 3072-bit parameters.\n",
726         "-p256       Measure ECC using P-256 curve.\n",
727         "-p384       Measure ECC using P-384 curve.\n",
728         "-ecc-all    Bench all enabled ECC curves.\n",
729         "-<alg>      Algorithm to benchmark. Available algorithms include:\n",
730         "-lng <num>  Display benchmark result by specified language.\n            0: English, 1: Japanese\n",
731         "<num>       Size of block in bytes\n",
732         "-threads <num> Number of threads to run\n",
733         "-print      Show benchmark stats summary\n"
734     },
735 #ifndef NO_MULTIBYTE_PRINT
736     /* 1 Japanese */
737     {   "-? <num>    ヘルプ, 使い方を表示します。\n            0: 英語、 1: 日本語\n",
738         "-csv        csv 形式で端末に出力します。\n",
739         "-base10     バイトを10のべき乗で表示します。(例 1 kB = 1000 Bytes)\n",
740         "-no_aad     追加の認証データを使用しません.\n",
741         "-dgst_full  フルの digest 暗号操作を実施します。\n",
742         "-rsa_sign   暗号/復号化の代わりに RSA の署名/検証を測定します。\n",
743         "<keySz> -rsa-sz\n            RSA <key size> の性能を測定します。\n",
744         "-ffhdhe2048 Measure DH using FFDHE 2048-bit parameters.\n",
745         "-ffhdhe3072 Measure DH using FFDHE 3072-bit parameters.\n",
746         "-p256       Measure ECC using P-256 curve.\n",
747         "-p384       Measure ECC using P-384 curve.\n",
748         "-ecc-all    Bench all enabled ECC curves.\n",
749         "-<alg>      アルゴリズムのベンチマークを実施します。\n            利用可能なアルゴリズムは下記を含みます:\n",
750         "-lng <num>  指定された言語でベンチマーク結果を表示します。\n            0: 英語、 1: 日本語\n",
751         "<num>       ブロックサイズをバイト単位で指定します。\n",
752         "-threads <num> 実行するスレッド数\n",
753         "-print      ベンチマーク統計の要約を表示する\n"
754     },
755 #endif
756 };
757 #endif /* MAIN_NO_ARGS */
758 #endif
759 
760 static const char* bench_result_words1[][4] = {
761     { "took", "seconds" , "Cycles per byte", NULL },           /* 0 English  */
762 #ifndef NO_MULTIBYTE_PRINT
763     { "を"   , "秒で処理", "1バイトあたりのサイクル数", NULL },     /* 1 Japanese */
764 #endif
765 };
766 
767 #if !defined(NO_RSA) || \
768     defined(HAVE_ECC) || !defined(NO_DH) || defined(HAVE_ECC_ENCRYPT) || \
769     defined(HAVE_CURVE25519) || defined(HAVE_CURVE25519_SHARED_SECRET)  || \
770     defined(HAVE_ED25519) || defined(HAVE_CURVE448) || \
771     defined(HAVE_CURVE448_SHARED_SECRET) || defined(HAVE_ED448)
772 
773 static const char* bench_desc_words[][14] = {
774     /* 0           1          2         3        4        5         6            7            8          9        10        11       12          13 */
775     {"public", "private", "key gen", "agree" , "sign", "verify", "encryption", "decryption", "rsk gen", "encap", "derive", "valid", "pair gen", NULL}, /* 0 English */
776 #ifndef NO_MULTIBYTE_PRINT
777     {"公開鍵", "秘密鍵" ,"鍵生成" , "鍵共有" , "署名", "検証"  , "暗号化"    , "復号化"    , "rsk gen", "encap", "derive", "valid", "pair gen", NULL}, /* 1 Japanese */
778 #endif
779 };
780 
781 #endif
782 
783 #if defined(__GNUC__) && defined(__x86_64__) && !defined(NO_ASM) && !defined(WOLFSSL_SGX)
784     #define HAVE_GET_CYCLES
785     static WC_INLINE word64 get_intel_cycles(void);
786     static THREAD_LS_T word64 total_cycles;
787     #define INIT_CYCLE_COUNTER
788     #define BEGIN_INTEL_CYCLES total_cycles = get_intel_cycles();
789     #define END_INTEL_CYCLES   total_cycles = get_intel_cycles() - total_cycles;
790     /* s == size in bytes that 1 count represents, normally BENCH_SIZE */
791     #define SHOW_INTEL_CYCLES(b, n, s) \
792         XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), " %s = %6.2f\n", \
793             bench_result_words1[lng_index][2], \
794             count == 0 ? 0 : (float)total_cycles / ((word64)count*s))
795     #define SHOW_INTEL_CYCLES_CSV(b, n, s) \
796         XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), "%.2f,\n", \
797             count == 0 ? 0 : (float)total_cycles / ((word64)count*s))
798 #elif defined(LINUX_CYCLE_COUNT)
799     #include <linux/perf_event.h>
800     #include <sys/syscall.h>
801     #include <unistd.h>
802 
803     static THREAD_LS_T word64 begin_cycles;
804     static THREAD_LS_T word64 total_cycles;
805     static THREAD_LS_T int cycles = -1;
806     static THREAD_LS_T struct perf_event_attr atr;
807 
808     #define INIT_CYCLE_COUNTER do { \
809         atr.type   = PERF_TYPE_HARDWARE; \
810         atr.config = PERF_COUNT_HW_CPU_CYCLES; \
811         cycles = (int)syscall(__NR_perf_event_open, &atr, 0, -1, -1, 0); \
812     } while (0);
813 
814     #define BEGIN_INTEL_CYCLES read(cycles, &begin_cycles, sizeof(begin_cycles));
815     #define END_INTEL_CYCLES   do { \
816         read(cycles, &total_cycles, sizeof(total_cycles)); \
817         total_cycles = total_cycles - begin_cycles; \
818     } while (0);
819 
820     /* s == size in bytes that 1 count represents, normally BENCH_SIZE */
821     #define SHOW_INTEL_CYCLES(b, n, s) \
822         XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), " %s = %6.2f\n", \
823         bench_result_words1[lng_index][2], \
824             (float)total_cycles / (count*s))
825     #define SHOW_INTEL_CYCLES_CSV(b, n, s) \
826         XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), "%.2f,\n", \
827             (float)total_cycles / (count*s))
828 
829 #elif defined(SYNERGY_CYCLE_COUNT)
830     #include "hal_data.h"
831     static THREAD_LS_T word64 begin_cycles;
832     static THREAD_LS_T word64 total_cycles;
833 
834     #define INIT_CYCLE_COUNTER
835     #define BEGIN_INTEL_CYCLES begin_cycles = DWT->CYCCNT = 0;
836     #define END_INTEL_CYCLES   total_cycles =  DWT->CYCCNT - begin_cycles;
837 
838     /* s == size in bytes that 1 count represents, normally BENCH_SIZE */
839     #define SHOW_INTEL_CYCLES(b, n, s) \
840         XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), " %s = %6.2f\n", \
841         bench_result_words1[lng_index][2], \
842             (float)total_cycles / (count*s))
843     #define SHOW_INTEL_CYCLES_CSV(b, n, s) \
844         XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), "%.2f,\n", \
845             (float)total_cycles / (count*s))
846 
847 #else
848     #define INIT_CYCLE_COUNTER
849     #define BEGIN_INTEL_CYCLES
850     #define END_INTEL_CYCLES
851     #define SHOW_INTEL_CYCLES(b, n, s)     b[XSTRLEN(b)] = '\n'
852     #define SHOW_INTEL_CYCLES_CSV(b, n, s)     b[XSTRLEN(b)] = '\n'
853 #endif
854 
855 /* determine benchmark buffer to use (if NO_FILESYSTEM) */
856 #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \
857     !defined(USE_CERT_BUFFERS_3072)
858     #define USE_CERT_BUFFERS_2048 /* default to 2048 */
859 #endif
860 
861 #if defined(USE_CERT_BUFFERS_1024) || defined(USE_CERT_BUFFERS_2048) || \
862     defined(USE_CERT_BUFFERS_3072) || !defined(NO_DH)
863     /* include test cert and key buffers for use with NO_FILESYSTEM */
864     #include <wolfssl/certs_test.h>
865 #endif
866 
867 #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S)
868     #include <wolfssl/wolfcrypt/blake2.h>
869 #endif
870 
871 #ifdef _MSC_VER
872     /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
873     #pragma warning(disable: 4996)
874 #endif
875 
876 
877 #ifdef WOLFSSL_CURRTIME_REMAP
878     #define current_time WOLFSSL_CURRTIME_REMAP
879 #elif !defined(HAVE_STACK_SIZE)
880     double current_time(int);
881 #endif
882 
883 #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) && \
884         !defined(HAVE_STACK_SIZE)
885 #ifdef __cplusplus
886     extern "C" {
887 #endif
888     WOLFSSL_API int wolfSSL_Debugging_ON(void);
889     WOLFSSL_API void wolfSSL_Debugging_OFF(void);
890 #ifdef __cplusplus
891     }  /* extern "C" */
892 #endif
893 #endif
894 
895 #if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WC_NO_RNG)) \
896         || !defined(NO_DH) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) \
897         || defined(HAVE_CURVE25519) || defined(HAVE_ED25519) \
898         || defined(HAVE_CURVE448) || defined(HAVE_ED448)
899     #define HAVE_LOCAL_RNG
900     static THREAD_LS_T WC_RNG gRng;
901     #define GLOBAL_RNG &gRng
902 #else
903     #define GLOBAL_RNG NULL
904 #endif
905 
906 #if defined(HAVE_ED25519) || defined(HAVE_CURVE25519) || \
907     defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
908     defined(HAVE_ECC) || !defined(NO_DH) || \
909     !defined(NO_RSA) || defined(HAVE_SCRYPT)
910     #define BENCH_ASYM
911 #endif
912 
913 #if defined(BENCH_ASYM)
914 #if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
915     defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \
916     defined(HAVE_CURVE448) || defined(HAVE_ED448)
917 static const char* bench_result_words2[][5] = {
918     { "ops took", "sec"     , "avg" , "ops/sec", NULL },            /* 0 English  */
919 #ifndef NO_MULTIBYTE_PRINT
920     { "回処理を", "秒で実施", "平均", "処理/秒", NULL },            /* 1 Japanese */
921 #endif
922 };
923 #endif
924 #endif
925 
926 /* Asynchronous helper macros */
927 #ifdef WOLFSSL_QNX_CAAM
928 #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
929 static THREAD_LS_T int devId = WOLFSSL_CAAM_DEVID;
930 #else
931 static THREAD_LS_T int devId = INVALID_DEVID;
932 #endif
933 
934 #ifdef WOLFSSL_ASYNC_CRYPT
935     static WOLF_EVENT_QUEUE eventQueue;
936 
937     #define BENCH_ASYNC_GET_DEV(obj)      (&(obj)->asyncDev)
938     #define BENCH_ASYNC_GET_NAME(doAsync) (doAsync) ? "HW" : "SW"
939     #define BENCH_MAX_PENDING             (WOLF_ASYNC_MAX_PENDING)
940 
941 #ifndef WC_NO_ASYNC_THREADING
942     typedef struct ThreadData {
943         pthread_t thread_id;
944     } ThreadData;
945     static ThreadData* g_threadData;
946     static int g_threadCount;
947 #endif
948 
bench_async_check(int * ret,WC_ASYNC_DEV * asyncDev,int callAgain,int * times,int limit,int * pending)949     static int bench_async_check(int* ret, WC_ASYNC_DEV* asyncDev,
950         int callAgain, int* times, int limit, int* pending)
951     {
952         int allowNext = 0;
953 
954         /* this state can be set from a different thread */
955         WOLF_EVENT_STATE state = asyncDev->event.state;
956 
957         /* if algo doesn't require calling again then use this flow */
958         if (state == WOLF_EVENT_STATE_DONE) {
959             if (callAgain) {
960                 /* needs called again, so allow it and handle completion in bench_async_handle */
961                 allowNext = 1;
962             }
963             else {
964                 *ret = asyncDev->event.ret;
965                 asyncDev->event.state = WOLF_EVENT_STATE_READY;
966                 (*times)++;
967                 if (*pending > 0) /* to support case where async blocks */
968                     (*pending)--;
969 
970                 if ((*times + *pending) < limit)
971                     allowNext = 1;
972             }
973         }
974 
975         /* if slot is available and we haven't reached limit, start another */
976         else if (state == WOLF_EVENT_STATE_READY && (*times + *pending) < limit) {
977             allowNext = 1;
978         }
979 
980         return allowNext;
981     }
982 
bench_async_handle(int * ret,WC_ASYNC_DEV * asyncDev,int callAgain,int * times,int * pending)983     static int bench_async_handle(int* ret, WC_ASYNC_DEV* asyncDev,
984         int callAgain, int* times, int* pending)
985     {
986         WOLF_EVENT_STATE state = asyncDev->event.state;
987 
988         if (*ret == WC_PENDING_E) {
989             if (state == WOLF_EVENT_STATE_DONE) {
990                 *ret = asyncDev->event.ret;
991                 asyncDev->event.state = WOLF_EVENT_STATE_READY;
992                 (*times)++;
993                 (*pending)--;
994             }
995             else {
996                 (*pending)++;
997                 *ret = wc_AsyncHandle(asyncDev, &eventQueue,
998                     callAgain ? WC_ASYNC_FLAG_CALL_AGAIN : WC_ASYNC_FLAG_NONE);
999             }
1000         }
1001         else if (*ret >= 0) {
1002             *ret = asyncDev->event.ret;
1003             asyncDev->event.state = WOLF_EVENT_STATE_READY;
1004             (*times)++;
1005             if (*pending > 0)  /* to support case where async blocks */
1006                 (*pending)--;
1007         }
1008 
1009         return (*ret >= 0) ? 1 : 0;
1010     }
1011 
bench_async_poll(int * pending)1012     static WC_INLINE int bench_async_poll(int* pending)
1013     {
1014         int ret, asyncDone = 0;
1015 
1016         ret = wolfAsync_EventQueuePoll(&eventQueue, NULL, NULL, 0,
1017                                        WOLF_POLL_FLAG_CHECK_HW, &asyncDone);
1018         if (ret != 0) {
1019             printf("Async poll failed %d\n", ret);
1020             return ret;
1021         }
1022 
1023         if (asyncDone == 0) {
1024         #ifndef WC_NO_ASYNC_THREADING
1025             /* give time to other threads */
1026             wc_AsyncThreadYield();
1027         #endif
1028         }
1029 
1030         (void)pending;
1031 
1032         return asyncDone;
1033     }
1034 
1035 #else
1036     #define BENCH_MAX_PENDING             (1)
1037     #define BENCH_ASYNC_GET_NAME(doAsync) ""
1038     #define BENCH_ASYNC_GET_DEV(obj)      NULL
1039 
bench_async_check(int * ret,void * asyncDev,int callAgain,int * times,int limit,int * pending)1040     static WC_INLINE int bench_async_check(int* ret, void* asyncDev,
1041         int callAgain, int* times, int limit, int* pending)
1042     {
1043         (void)ret;
1044         (void)asyncDev;
1045         (void)callAgain;
1046         (void)times;
1047         (void)limit;
1048         (void)pending;
1049 
1050         return 1;
1051     }
1052 
bench_async_handle(int * ret,void * asyncDev,int callAgain,int * times,int * pending)1053     static WC_INLINE int bench_async_handle(int* ret, void* asyncDev,
1054         int callAgain, int* times, int* pending)
1055     {
1056         (void)asyncDev;
1057         (void)callAgain;
1058         (void)pending;
1059 
1060         if (*ret >= 0) {
1061             /* operation completed */
1062             (*times)++;
1063             return 1;
1064         }
1065         return 0;
1066     }
1067     #define bench_async_poll(p)
1068 #endif /* WOLFSSL_ASYNC_CRYPT */
1069 
1070 
1071 
1072 /* maximum runtime for each benchmark */
1073 #define BENCH_MIN_RUNTIME_SEC   1.0f
1074 
1075 
1076 #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
1077     #if !defined(AES_AUTH_ADD_SZ) && \
1078             defined(STM32_CRYPTO) && !defined(STM32_AESGCM_PARTIAL)
1079         /* For STM32 use multiple of 4 to leverage crypto hardware */
1080         #define AES_AUTH_ADD_SZ 16
1081     #endif
1082     #ifndef AES_AUTH_ADD_SZ
1083     #define AES_AUTH_ADD_SZ 13
1084     #endif
1085     #define AES_AUTH_TAG_SZ 16
1086     #define BENCH_CIPHER_ADD AES_AUTH_TAG_SZ
1087     static word32 aesAuthAddSz = AES_AUTH_ADD_SZ;
1088 #endif
1089 #ifndef BENCH_CIPHER_ADD
1090     #define BENCH_CIPHER_ADD 0
1091 #endif
1092 
1093 
1094 /* use kB instead of mB for embedded benchmarking */
1095 #ifdef BENCH_EMBEDDED
1096     enum BenchmarkBounds {
1097         scryptCnt  = 1,
1098         ntimes     = 2,
1099         genTimes   = BENCH_MAX_PENDING,
1100         agreeTimes = 2
1101     };
1102     static int    numBlocks  = 25; /* how many kB to test (en/de)cryption */
1103     static word32 bench_size = (1024ul);
1104 #else
1105     enum BenchmarkBounds {
1106         scryptCnt  = 10,
1107         ntimes     = 100,
1108         genTimes   = BENCH_MAX_PENDING, /* must be at least BENCH_MAX_PENDING */
1109         agreeTimes = 100
1110     };
1111     static int    numBlocks  = 5; /* how many megs to test (en/de)cryption */
1112     static word32 bench_size = (1024*1024ul);
1113 #endif
1114 static int base2 = 1;
1115 static int digest_stream = 1;
1116 #ifndef NO_RSA
1117 /* Don't measure RSA sign/verify by default */
1118 static int rsa_sign_verify = 0;
1119 #endif
1120 #ifndef NO_DH
1121 /* Use the FFDHE parameters */
1122 static int use_ffdhe = 0;
1123 #endif
1124 
1125 /* Don't print out in CSV format by default */
1126 static int csv_format = 0;
1127 #ifdef BENCH_ASYM
1128 static int csv_header_count = 0;
1129 #endif
1130 
1131 /* for compatibility */
1132 #define BENCH_SIZE bench_size
1133 
1134 /* globals for cipher tests */
1135 static THREAD_LS_T byte* bench_plain = NULL;
1136 static THREAD_LS_T byte* bench_cipher = NULL;
1137 
1138 static const XGEN_ALIGN byte bench_key_buf[] =
1139 {
1140     0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
1141     0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10,
1142     0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67,
1143     0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
1144 };
1145 
1146 static const XGEN_ALIGN byte bench_iv_buf[] =
1147 {
1148     0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef,
1149     0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
1150     0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81
1151 };
1152 static THREAD_LS_T byte* bench_key = NULL;
1153 static THREAD_LS_T byte* bench_iv = NULL;
1154 
1155 #ifdef WOLFSSL_STATIC_MEMORY
1156     #ifdef BENCH_EMBEDDED
1157         static byte gBenchMemory[50000];
1158     #else
1159         static byte gBenchMemory[400000];
1160     #endif
1161 #endif
1162 
1163 
1164 /* This code handles cases with systems where static (non cost) ram variables
1165     aren't properly initialized with data */
1166 static int gBenchStaticInit = 0;
benchmark_static_init(void)1167 static void benchmark_static_init(void)
1168 {
1169     if (gBenchStaticInit == 0) {
1170         gBenchStaticInit = 1;
1171 
1172         /* Init static variables */
1173         bench_all = 1;
1174     #ifdef BENCH_EMBEDDED
1175         numBlocks  = 25; /* how many kB to test (en/de)cryption */
1176         bench_size = (1024ul);
1177     #else
1178         numBlocks  = 5; /* how many megs to test (en/de)cryption */
1179         bench_size = (1024*1024ul);
1180     #endif
1181     #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
1182         aesAuthAddSz = AES_AUTH_ADD_SZ;
1183     #endif
1184         base2 = 1;
1185         digest_stream = 1;
1186     }
1187 }
1188 
1189 
1190 
1191 /******************************************************************************/
1192 /* Begin Stats Functions */
1193 /******************************************************************************/
1194 static int gPrintStats = 0;
1195 typedef enum bench_stat_type {
1196     BENCH_STAT_ASYM,
1197     BENCH_STAT_SYM,
1198 } bench_stat_type_t;
1199 #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING)
1200     #ifndef BENCH_MAX_NAME_SZ
1201     #define BENCH_MAX_NAME_SZ 24
1202     #endif
1203     typedef struct bench_stats {
1204         struct bench_stats* next;
1205         struct bench_stats* prev;
1206         char algo[BENCH_MAX_NAME_SZ+1]; /* may not be static, so make copy */
1207         const char* desc;
1208         double perfsec;
1209         int strength;
1210         int doAsync;
1211         int finishCount;
1212         bench_stat_type_t type;
1213         int lastRet;
1214         const char* perftype;
1215     } bench_stats_t;
1216     static bench_stats_t* bench_stats_head;
1217     static bench_stats_t* bench_stats_tail;
1218     static pthread_mutex_t bench_lock = PTHREAD_MUTEX_INITIALIZER;
1219 
bench_stats_add(bench_stat_type_t type,const char * algo,int strength,const char * desc,int doAsync,double perfsec,const char * perftype,int ret)1220     static bench_stats_t* bench_stats_add(bench_stat_type_t type,
1221         const char* algo, int strength, const char* desc, int doAsync,
1222         double perfsec, const char* perftype, int ret)
1223     {
1224         bench_stats_t* bstat = NULL;
1225 
1226         /* protect bench_stats_head and bench_stats_tail access */
1227         pthread_mutex_lock(&bench_lock);
1228 
1229         if (algo != NULL) {
1230             /* locate existing in list */
1231             for (bstat = bench_stats_head; bstat != NULL; bstat = bstat->next) {
1232                 /* match based on algo, strength and desc */
1233                 if (XSTRNCMP(bstat->algo, algo, BENCH_MAX_NAME_SZ) == 0 &&
1234                     bstat->strength == strength &&
1235                     bstat->desc == desc &&
1236                     bstat->doAsync == doAsync) {
1237                     break;
1238                 }
1239             }
1240         }
1241 
1242         if (bstat == NULL) {
1243             /* allocate new and put on list */
1244             bstat = (bench_stats_t*)XMALLOC(sizeof(bench_stats_t), NULL, DYNAMIC_TYPE_INFO);
1245             if (bstat) {
1246                 XMEMSET(bstat, 0, sizeof(bench_stats_t));
1247 
1248                 /* add to list */
1249                 bstat->next = NULL;
1250                 if (bench_stats_tail == NULL)  {
1251                     bench_stats_head = bstat;
1252                 }
1253                 else {
1254                     bench_stats_tail->next = bstat;
1255                     bstat->prev = bench_stats_tail;
1256                 }
1257                 bench_stats_tail = bstat; /* add to the end either way */
1258             }
1259         }
1260         if (bstat) {
1261             bstat->type = type;
1262             if (algo != NULL)
1263                 XSTRNCPY(bstat->algo, algo, BENCH_MAX_NAME_SZ);
1264             bstat->strength = strength;
1265             bstat->desc = desc;
1266             bstat->doAsync = doAsync;
1267             bstat->perfsec += perfsec;
1268             bstat->finishCount++;
1269             bstat->perftype = perftype;
1270             if (bstat->lastRet > ret)
1271                 bstat->lastRet = ret; /* track last error */
1272         }
1273         pthread_mutex_unlock(&bench_lock);
1274 
1275         return bstat;
1276     }
1277 
bench_stats_print(void)1278     void bench_stats_print(void)
1279     {
1280         bench_stats_t* bstat;
1281 
1282         /* protect bench_stats_head and bench_stats_tail access */
1283         pthread_mutex_lock(&bench_lock);
1284 
1285         for (bstat = bench_stats_head; bstat != NULL; ) {
1286             if (bstat->type == BENCH_STAT_SYM) {
1287                 printf("%-16s%s %8.3f %s/s\n", bstat->desc,
1288                     BENCH_ASYNC_GET_NAME(bstat->doAsync), bstat->perfsec,
1289                     base2 ? "MB" : "mB");
1290             }
1291             else {
1292                 printf("%-5s %4d %-9s %s %.3f ops/sec\n",
1293                     bstat->algo, bstat->strength, bstat->desc,
1294                     BENCH_ASYNC_GET_NAME(bstat->doAsync), bstat->perfsec);
1295             }
1296 
1297             bstat = bstat->next;
1298         }
1299 
1300         pthread_mutex_unlock(&bench_lock);
1301     }
1302 
1303 #else
1304 
1305     typedef struct bench_stats {
1306         const char* algo;
1307         const char* desc;
1308         double perfsec;
1309         const char* perftype;
1310         int strength;
1311         bench_stat_type_t type;
1312         int ret;
1313     } bench_stats_t;
1314     #define MAX_BENCH_STATS 50
1315     static bench_stats_t gStats[MAX_BENCH_STATS];
1316     static int gStatsCount;
1317 
bench_stats_add(bench_stat_type_t type,const char * algo,int strength,const char * desc,int doAsync,double perfsec,const char * perftype,int ret)1318     static bench_stats_t* bench_stats_add(bench_stat_type_t type,
1319             const char* algo, int strength, const char* desc, int doAsync,
1320             double perfsec, const char* perftype, int ret)
1321     {
1322         bench_stats_t* bstat = NULL;
1323         if (gStatsCount >= MAX_BENCH_STATS)
1324             return bstat;
1325 
1326         bstat = &gStats[gStatsCount++];
1327         bstat->algo = algo;
1328         bstat->desc = desc;
1329         bstat->perfsec = perfsec;
1330         bstat->perftype = perftype;
1331         bstat->strength = strength;
1332         bstat->type = type;
1333         bstat->ret = ret;
1334 
1335         (void)doAsync;
1336 
1337         return bstat;
1338     }
1339 
bench_stats_print(void)1340     void bench_stats_print(void)
1341     {
1342         int i;
1343         bench_stats_t* bstat;
1344         for (i=0; i<gStatsCount; i++) {
1345             bstat = &gStats[i];
1346             if (bstat->type == BENCH_STAT_SYM) {
1347                 printf("%-16s %8.3f %s/s\n", bstat->desc, bstat->perfsec,
1348                     base2 ? "MB" : "mB");
1349             }
1350             else {
1351                 printf("%-5s %4d %-9s %.3f ops/sec\n",
1352                     bstat->algo, bstat->strength, bstat->desc, bstat->perfsec);
1353             }
1354         }
1355     }
1356 #endif /* WOLFSSL_ASYNC_CRYPT && !WC_NO_ASYNC_THREADING */
1357 
bench_stats_init(void)1358 static WC_INLINE void bench_stats_init(void)
1359 {
1360 #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING)
1361     bench_stats_head = NULL;
1362     bench_stats_tail = NULL;
1363 #endif
1364     INIT_CYCLE_COUNTER
1365 }
1366 
bench_stats_start(int * count,double * start)1367 static WC_INLINE void bench_stats_start(int* count, double* start)
1368 {
1369     *count = 0;
1370     *start = current_time(1);
1371     BEGIN_INTEL_CYCLES
1372 }
1373 
bench_stats_sym_check(double start)1374 static WC_INLINE int bench_stats_sym_check(double start)
1375 {
1376     return ((current_time(0) - start) < BENCH_MIN_RUNTIME_SEC);
1377 }
1378 
1379 
1380 /* countSz is number of bytes that 1 count represents. Normally bench_size,
1381  * except for AES direct that operates on AES_BLOCK_SIZE blocks */
bench_stats_sym_finish(const char * desc,int doAsync,int count,int countSz,double start,int ret)1382 static void bench_stats_sym_finish(const char* desc, int doAsync, int count,
1383                                    int countSz, double start, int ret)
1384 {
1385     double total, persec = 0, blocks = count;
1386     const char* blockType;
1387     char msg[128] = {0};
1388     const char** word = bench_result_words1[lng_index];
1389 
1390     END_INTEL_CYCLES
1391     total = current_time(0) - start;
1392 
1393     /* calculate actual bytes */
1394     blocks *= countSz;
1395 
1396     if (base2) {
1397         /* determine if we should show as KB or MB */
1398         if (blocks > (1024ul * 1024ul)) {
1399             blocks /= (1024ul * 1024ul);
1400             blockType = "MB";
1401         }
1402         else if (blocks > 1024) {
1403             blocks /= 1024; /* make KB */
1404             blockType = "KB";
1405         }
1406         else {
1407             blockType = "bytes";
1408         }
1409     }
1410     else {
1411         /* determine if we should show as kB or mB */
1412         if (blocks > (1000ul * 1000ul)) {
1413             blocks /= (1000ul * 1000ul);
1414             blockType = "mB";
1415         }
1416         else if (blocks > 1000) {
1417             blocks /= 1000; /* make kB */
1418             blockType = "kB";
1419         }
1420         else {
1421             blockType = "bytes";
1422         }
1423     }
1424 
1425     /* calculate blocks per second */
1426     if (total > 0) {
1427         persec = (1 / total) * blocks;
1428     }
1429 
1430     /* format and print to terminal */
1431     if (csv_format == 1) {
1432         XSNPRINTF(msg, sizeof(msg), "%s,%.3f,", desc, persec);
1433         SHOW_INTEL_CYCLES_CSV(msg, sizeof(msg), countSz);
1434     } else {
1435         XSNPRINTF(msg, sizeof(msg), "%-16s%s %5.0f %s %s %5.3f %s, %8.3f %s/s",
1436         desc, BENCH_ASYNC_GET_NAME(doAsync), blocks, blockType, word[0], total, word[1],
1437         persec, blockType);
1438         SHOW_INTEL_CYCLES(msg, sizeof(msg), countSz);
1439     }
1440     printf("%s", msg);
1441 
1442     /* show errors */
1443     if (ret < 0) {
1444         printf("Benchmark %s failed: %d\n", desc, ret);
1445     }
1446 
1447     /* Add to thread stats */
1448     bench_stats_add(BENCH_STAT_SYM, NULL, 0, desc, doAsync, persec, blockType, ret);
1449 
1450     (void)doAsync;
1451     (void)ret;
1452 
1453     TEST_SLEEP();
1454 }
1455 
1456 #ifdef BENCH_ASYM
1457 #if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
1458     defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \
1459     defined(HAVE_CURVE448) || defined(HAVE_ED448)
bench_stats_asym_finish(const char * algo,int strength,const char * desc,int doAsync,int count,double start,int ret)1460 static void bench_stats_asym_finish(const char* algo, int strength,
1461     const char* desc, int doAsync, int count, double start, int ret)
1462 {
1463     double total, each = 0, opsSec, milliEach;
1464     const char **word = bench_result_words2[lng_index];
1465     const char* kOpsSec = "Ops/Sec";
1466     char msg[128] = {0};
1467 
1468     total = current_time(0) - start;
1469     if (count > 0)
1470         each  = total / count; /* per second  */
1471     opsSec = count / total;    /* ops second */
1472     milliEach = each * 1000;   /* milliseconds */
1473 
1474     /* format and print to terminal */
1475     if (csv_format == 1) {
1476         /* only print out header once */
1477         if (csv_header_count == 1) {
1478             printf("\nAsymmetric Ciphers:\n\n");
1479             printf("Algorithm,avg ms,ops/sec,\n");
1480             csv_header_count++;
1481         }
1482         XSNPRINTF(msg, sizeof(msg), "%s %d %s,%.3f,%.3f,\n", algo, strength, desc, milliEach, opsSec);
1483     } else {
1484         XSNPRINTF(msg, sizeof(msg), "%-6s %5d %-9s %s %6d %s %5.3f %s, %s %5.3f ms,"
1485         " %.3f %s\n", algo, strength, desc, BENCH_ASYNC_GET_NAME(doAsync),
1486         count, word[0], total, word[1], word[2], milliEach, opsSec, word[3]);
1487     }
1488     printf("%s", msg);
1489 
1490     /* show errors */
1491     if (ret < 0) {
1492         printf("Benchmark %s %s %d failed: %d\n", algo, desc, strength, ret);
1493     }
1494 
1495     /* Add to thread stats */
1496     bench_stats_add(BENCH_STAT_ASYM, algo, strength, desc, doAsync, opsSec, kOpsSec, ret);
1497 
1498     (void)doAsync;
1499     (void)ret;
1500 
1501     TEST_SLEEP();
1502 }
1503 #endif
1504 
1505 #if defined(HAVE_PQC)
bench_stats_pq_asym_finish(const char * algo,int doAsync,int count,double start,int ret)1506 static void bench_stats_pq_asym_finish(const char* algo, int doAsync, int count,
1507                                        double start, int ret)
1508 {
1509     double total, each = 0, opsSec, milliEach;
1510     const char **word = bench_result_words2[lng_index];
1511     const char* kOpsSec = "Ops/Sec";
1512     char msg[128] = {0};
1513 
1514     total = current_time(0) - start;
1515     if (count > 0)
1516         each  = total / count; /* per second  */
1517     opsSec = count / total;    /* ops second */
1518     milliEach = each * 1000;   /* milliseconds */
1519 
1520     /* format and print to terminal */
1521     if (csv_format == 1) {
1522         /* only print out header once */
1523         if (csv_header_count == 1) {
1524             printf("\nPost Quantum Asymmetric Ciphers:\n\n");
1525             printf("Algorithm,avg ms,ops/sec,\n");
1526             csv_header_count++;
1527         }
1528         XSNPRINTF(msg, sizeof(msg), "%s %.3f,%.3f,\n", algo, milliEach, opsSec);
1529     } else {
1530          XSNPRINTF(msg, sizeof(msg), "%-18s %s %6d %s %5.3f %s, %s %5.3f ms,"
1531          " %.3f %s\n", algo, BENCH_ASYNC_GET_NAME(doAsync),
1532          count, word[0], total, word[1], word[2], milliEach, opsSec, word[3]);
1533     }
1534     printf("%s", msg);
1535 
1536     /* show errors */
1537     if (ret < 0) {
1538         printf("Benchmark %s failed: %d\n", algo, ret);
1539     }
1540 
1541     /* Add to thread stats */
1542     bench_stats_add(BENCH_STAT_ASYM, algo, 0, "", doAsync, opsSec, kOpsSec, ret);
1543 
1544     (void)doAsync;
1545     (void)ret;
1546 
1547     TEST_SLEEP();
1548 }
1549 #endif
1550 #endif /* BENCH_ASYM */
1551 
bench_stats_free(void)1552 static WC_INLINE void bench_stats_free(void)
1553 {
1554 #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING)
1555     bench_stats_t* bstat;
1556     for (bstat = bench_stats_head; bstat != NULL; ) {
1557         bench_stats_t* next = bstat->next;
1558         XFREE(bstat, NULL, DYNAMIC_TYPE_INFO);
1559         bstat = next;
1560     }
1561     bench_stats_head = NULL;
1562     bench_stats_tail = NULL;
1563 #endif
1564 }
1565 /******************************************************************************/
1566 /* End Stats Functions */
1567 /******************************************************************************/
1568 
1569 
benchmarks_do(void * args)1570 static void* benchmarks_do(void* args)
1571 {
1572     int bench_buf_size;
1573 
1574 #ifdef WOLFSSL_ASYNC_CRYPT
1575 #ifndef WC_NO_ASYNC_THREADING
1576     ThreadData* threadData = (ThreadData*)args;
1577 
1578     if (wolfAsync_DevOpenThread(&devId, &threadData->thread_id) < 0)
1579 #else
1580     if (wolfAsync_DevOpen(&devId) < 0)
1581 #endif
1582     {
1583         printf("Async device open failed\nRunning without async\n");
1584     }
1585 #endif /* WOLFSSL_ASYNC_CRYPT */
1586 
1587     (void)args;
1588 
1589 #ifdef WOLFSSL_ASYNC_CRYPT
1590     if (wolfEventQueue_Init(&eventQueue) != 0) {
1591         printf("Async event queue init failure!\n");
1592     }
1593 #endif
1594 
1595 #ifdef WOLF_CRYPTO_CB
1596 #ifdef HAVE_INTEL_QA_SYNC
1597     devId = wc_CryptoCb_InitIntelQa();
1598     if (devId == INVALID_DEVID) {
1599         printf("Couldn't init the Intel QA\n");
1600     }
1601 #endif
1602 #ifdef HAVE_CAVIUM_OCTEON_SYNC
1603     devId = wc_CryptoCb_InitOcteon();
1604     if (devId == INVALID_DEVID) {
1605         printf("Couldn't get the Octeon device ID\n");
1606     }
1607 #endif
1608 #ifdef HAVE_RENESAS_SYNC
1609     devId = wc_CryptoCb_CryptInitRenesasCmn(NULL, &guser_PKCbInfo);
1610     if (devId == INVALID_DEVID) {
1611         printf("Couldn't get the Renesas device ID\n");
1612     }
1613 #endif
1614 #endif
1615 
1616 #if defined(HAVE_LOCAL_RNG)
1617     {
1618         int rngRet;
1619 
1620 #ifndef HAVE_FIPS
1621         rngRet = wc_InitRng_ex(&gRng, HEAP_HINT, devId);
1622 #else
1623         rngRet = wc_InitRng(&gRng);
1624 #endif
1625         if (rngRet < 0) {
1626             printf("InitRNG failed\n");
1627             return NULL;
1628         }
1629     }
1630 #endif
1631 
1632     /* setup bench plain, cipher, key and iv globals */
1633     /* make sure bench buffer is multiple of 16 (AES block size) */
1634     bench_buf_size = (int)bench_size + BENCH_CIPHER_ADD;
1635     if (bench_buf_size % 16)
1636         bench_buf_size += 16 - (bench_buf_size % 16);
1637 
1638 #ifdef WOLFSSL_AFALG_XILINX_AES
1639     bench_plain = (byte*)aligned_alloc(64, (size_t)bench_buf_size + 16);
1640     bench_cipher = (byte*)aligned_alloc(64, (size_t)bench_buf_size + 16);
1641 #else
1642     bench_plain = (byte*)XMALLOC((size_t)bench_buf_size + 16, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1643     bench_cipher = (byte*)XMALLOC((size_t)bench_buf_size + 16, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1644 #endif
1645     if (bench_plain == NULL || bench_cipher == NULL) {
1646         XFREE(bench_plain, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1647         XFREE(bench_cipher, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1648         bench_plain = bench_cipher = NULL;
1649 
1650         printf("Benchmark block buffer alloc failed!\n");
1651         goto exit;
1652     }
1653     XMEMSET(bench_plain, 0, (size_t)bench_buf_size);
1654     XMEMSET(bench_cipher, 0, (size_t)bench_buf_size);
1655 
1656 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(HAVE_INTEL_QA_SYNC)
1657     bench_key = (byte*)XMALLOC(sizeof(bench_key_buf), HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1658     bench_iv = (byte*)XMALLOC(sizeof(bench_iv_buf), HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1659     if (bench_key == NULL || bench_iv == NULL) {
1660         XFREE(bench_key, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1661         XFREE(bench_iv, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
1662         bench_key = bench_iv = NULL;
1663 
1664         printf("Benchmark cipher buffer alloc failed!\n");
1665         goto exit;
1666     }
1667     XMEMCPY(bench_key, bench_key_buf, sizeof(bench_key_buf));
1668     XMEMCPY(bench_iv, bench_iv_buf, sizeof(bench_iv_buf));
1669 #else
1670     bench_key = (byte*)bench_key_buf;
1671     bench_iv = (byte*)bench_iv_buf;
1672 #endif
1673 
1674 #ifndef WC_NO_RNG
1675     if (bench_all || (bench_other_algs & BENCH_RNG))
1676         bench_rng();
1677 #endif /* WC_NO_RNG */
1678 #ifndef NO_AES
1679 #ifdef HAVE_AES_CBC
1680     if (bench_all || (bench_cipher_algs & BENCH_AES_CBC)) {
1681     #ifndef NO_SW_BENCH
1682         bench_aescbc(0);
1683     #endif
1684     #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \
1685          defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC) || \
1686          defined(HAVE_RENESAS_SYNC)) && \
1687         !defined(NO_HW_BENCH)
1688         bench_aescbc(1);
1689     #endif
1690     }
1691 #endif
1692 #ifdef HAVE_AESGCM
1693     if (bench_all || (bench_cipher_algs & BENCH_AES_GCM)) {
1694     #ifndef NO_SW_BENCH
1695         bench_aesgcm(0);
1696     #endif
1697     #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \
1698          defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC) || \
1699          defined(HAVE_RENESAS_SYNC)) && \
1700         !defined(NO_HW_BENCH)
1701         bench_aesgcm(1);
1702     #endif
1703 
1704         bench_gmac();
1705     }
1706 #endif
1707 #ifdef WOLFSSL_AES_DIRECT
1708     if (bench_all || (bench_cipher_algs & BENCH_AES_ECB)) {
1709     #ifndef NO_SW_BENCH
1710         bench_aesecb(0);
1711     #endif
1712     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES) && \
1713         !defined(NO_HW_BENCH)
1714         bench_aesecb(1);
1715     #endif
1716     }
1717 #endif
1718 #ifdef WOLFSSL_AES_XTS
1719     if (bench_all || (bench_cipher_algs & BENCH_AES_XTS))
1720         bench_aesxts();
1721 #endif
1722 #ifdef WOLFSSL_AES_CFB
1723     if (bench_all || (bench_cipher_algs & BENCH_AES_CFB))
1724         bench_aescfb();
1725 #endif
1726 #ifdef WOLFSSL_AES_OFB
1727     if (bench_all || (bench_cipher_algs & BENCH_AES_OFB))
1728         bench_aesofb();
1729 #endif
1730 #ifdef WOLFSSL_AES_COUNTER
1731     if (bench_all || (bench_cipher_algs & BENCH_AES_CTR))
1732         bench_aesctr();
1733 #endif
1734 #ifdef HAVE_AESCCM
1735     if (bench_all || (bench_cipher_algs & BENCH_AES_CCM))
1736         bench_aesccm();
1737 #endif
1738 #endif /* !NO_AES */
1739 
1740 #ifdef HAVE_CAMELLIA
1741     if (bench_all || (bench_cipher_algs & BENCH_CAMELLIA))
1742         bench_camellia();
1743 #endif
1744 #ifndef NO_RC4
1745     if (bench_all || (bench_cipher_algs & BENCH_ARC4)) {
1746     #ifndef NO_SW_BENCH
1747         bench_arc4(0);
1748     #endif
1749     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ARC4) && \
1750         !defined(NO_HW_BENCH)
1751         bench_arc4(1);
1752     #endif
1753     }
1754 #endif
1755 #ifdef HAVE_HC128
1756     if (bench_all || (bench_cipher_algs & BENCH_HC128))
1757         bench_hc128();
1758 #endif
1759 #ifndef NO_RABBIT
1760     if (bench_all || (bench_cipher_algs & BENCH_RABBIT))
1761         bench_rabbit();
1762 #endif
1763 #ifdef HAVE_CHACHA
1764     if (bench_all || (bench_cipher_algs & BENCH_CHACHA20))
1765         bench_chacha();
1766 #endif
1767 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
1768     if (bench_all || (bench_cipher_algs & BENCH_CHACHA20_POLY1305))
1769         bench_chacha20_poly1305_aead();
1770 #endif
1771 #ifndef NO_DES3
1772     if (bench_all || (bench_cipher_algs & BENCH_DES)) {
1773     #ifndef NO_SW_BENCH
1774         bench_des(0);
1775     #endif
1776     #if ((defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)) || \
1777          defined(HAVE_INTEL_QA_SYNC) || defined(HAVE_CAVIUM_OCTEON_SYNC)) && \
1778         !defined(NO_HW_BENCH)
1779         bench_des(1);
1780     #endif
1781     }
1782 #endif
1783 #ifdef HAVE_IDEA
1784     if (bench_all || (bench_cipher_algs & BENCH_IDEA))
1785         bench_idea();
1786 #endif
1787 
1788 #ifndef NO_MD5
1789     if (bench_all || (bench_digest_algs & BENCH_MD5)) {
1790     #ifndef NO_SW_BENCH
1791         bench_md5(0);
1792     #endif
1793     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) && \
1794         !defined(NO_HW_BENCH)
1795         bench_md5(1);
1796     #endif
1797     }
1798 #endif
1799 #ifdef HAVE_POLY1305
1800     if (bench_all || (bench_digest_algs & BENCH_POLY1305))
1801         bench_poly1305();
1802 #endif
1803 #ifndef NO_SHA
1804     if (bench_all || (bench_digest_algs & BENCH_SHA)) {
1805     #ifndef NO_SW_BENCH
1806         bench_sha(0);
1807     #endif
1808     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA) && \
1809         !defined(NO_HW_BENCH)
1810         bench_sha(1);
1811     #endif
1812     }
1813 #endif
1814 #ifdef WOLFSSL_SHA224
1815     if (bench_all || (bench_digest_algs & BENCH_SHA224)) {
1816     #ifndef NO_SW_BENCH
1817         bench_sha224(0);
1818     #endif
1819     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224) && \
1820         !defined(NO_HW_BENCH)
1821         bench_sha224(1);
1822     #endif
1823     }
1824 #endif
1825 #ifndef NO_SHA256
1826     if (bench_all || (bench_digest_algs & BENCH_SHA256)) {
1827     #ifndef NO_SW_BENCH
1828         bench_sha256(0);
1829     #endif
1830     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256) && \
1831         !defined(NO_HW_BENCH)
1832         bench_sha256(1);
1833     #endif
1834     }
1835 #endif
1836 #ifdef WOLFSSL_SHA384
1837     if (bench_all || (bench_digest_algs & BENCH_SHA384)) {
1838     #ifndef NO_SW_BENCH
1839         bench_sha384(0);
1840     #endif
1841     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384) && \
1842         !defined(NO_HW_BENCH)
1843         bench_sha384(1);
1844     #endif
1845     }
1846 #endif
1847 #ifdef WOLFSSL_SHA512
1848     if (bench_all || (bench_digest_algs & BENCH_SHA512)) {
1849     #ifndef NO_SW_BENCH
1850         bench_sha512(0);
1851     #endif
1852     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) && \
1853         !defined(NO_HW_BENCH)
1854         bench_sha512(1);
1855     #endif
1856     }
1857 #endif
1858 #ifdef WOLFSSL_SHA3
1859     #ifndef WOLFSSL_NOSHA3_224
1860     if (bench_all || (bench_digest_algs & BENCH_SHA3_224)) {
1861     #ifndef NO_SW_BENCH
1862         bench_sha3_224(0);
1863     #endif
1864     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) && \
1865         !defined(NO_HW_BENCH)
1866         bench_sha3_224(1);
1867     #endif
1868     }
1869     #endif /* WOLFSSL_NOSHA3_224 */
1870     #ifndef WOLFSSL_NOSHA3_256
1871     if (bench_all || (bench_digest_algs & BENCH_SHA3_256)) {
1872     #ifndef NO_SW_BENCH
1873         bench_sha3_256(0);
1874     #endif
1875     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) && \
1876         !defined(NO_HW_BENCH)
1877         bench_sha3_256(1);
1878     #endif
1879     }
1880     #endif /* WOLFSSL_NOSHA3_256 */
1881     #ifndef WOLFSSL_NOSHA3_384
1882     if (bench_all || (bench_digest_algs & BENCH_SHA3_384)) {
1883     #ifndef NO_SW_BENCH
1884         bench_sha3_384(0);
1885     #endif
1886     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) && \
1887         !defined(NO_HW_BENCH)
1888         bench_sha3_384(1);
1889     #endif
1890     }
1891     #endif /* WOLFSSL_NOSHA3_384 */
1892     #ifndef WOLFSSL_NOSHA3_512
1893     if (bench_all || (bench_digest_algs & BENCH_SHA3_512)) {
1894     #ifndef NO_SW_BENCH
1895         bench_sha3_512(0);
1896     #endif
1897     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) && \
1898         !defined(NO_HW_BENCH)
1899         bench_sha3_512(1);
1900     #endif
1901     }
1902     #endif /* WOLFSSL_NOSHA3_512 */
1903 #endif
1904 #ifdef WOLFSSL_RIPEMD
1905     if (bench_all || (bench_digest_algs & BENCH_RIPEMD))
1906         bench_ripemd();
1907 #endif
1908 #ifdef HAVE_BLAKE2
1909     if (bench_all || (bench_digest_algs & BENCH_BLAKE2B))
1910         bench_blake2b();
1911 #endif
1912 #ifdef HAVE_BLAKE2S
1913     if (bench_all || (bench_digest_algs & BENCH_BLAKE2S))
1914         bench_blake2s();
1915 #endif
1916 #ifdef WOLFSSL_CMAC
1917     if (bench_all || (bench_mac_algs & BENCH_CMAC))
1918         bench_cmac();
1919 #endif
1920 
1921 #ifndef NO_HMAC
1922     #ifndef NO_MD5
1923         if (bench_all || (bench_mac_algs & BENCH_HMAC_MD5)) {
1924         #ifndef NO_SW_BENCH
1925             bench_hmac_md5(0);
1926         #endif
1927         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) && \
1928                 defined(WC_ASYNC_ENABLE_MD5) && !defined(NO_HW_BENCH)
1929             bench_hmac_md5(1);
1930         #endif
1931         }
1932     #endif
1933     #ifndef NO_SHA
1934         if (bench_all || (bench_mac_algs & BENCH_HMAC_SHA)) {
1935         #ifndef NO_SW_BENCH
1936             bench_hmac_sha(0);
1937         #endif
1938         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) && \
1939                 defined(WC_ASYNC_ENABLE_SHA) && !defined(NO_HW_BENCH)
1940             bench_hmac_sha(1);
1941         #endif
1942         }
1943     #endif
1944     #ifdef WOLFSSL_SHA224
1945         if (bench_all || (bench_mac_algs & BENCH_HMAC_SHA224)) {
1946         #ifndef NO_SW_BENCH
1947             bench_hmac_sha224(0);
1948         #endif
1949         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) && \
1950                 defined(WC_ASYNC_ENABLE_SHA224) && !defined(NO_HW_BENCH)
1951             bench_hmac_sha224(1);
1952         #endif
1953         }
1954     #endif
1955     #ifndef NO_SHA256
1956         if (bench_all || (bench_mac_algs & BENCH_HMAC_SHA256)) {
1957         #ifndef NO_SW_BENCH
1958             bench_hmac_sha256(0);
1959         #endif
1960         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) && \
1961                 defined(WC_ASYNC_ENABLE_SHA256) && !defined(NO_HW_BENCH)
1962             bench_hmac_sha256(1);
1963         #endif
1964         }
1965     #endif
1966     #ifdef WOLFSSL_SHA384
1967         if (bench_all || (bench_mac_algs & BENCH_HMAC_SHA384)) {
1968         #ifndef NO_SW_BENCH
1969             bench_hmac_sha384(0);
1970         #endif
1971         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) && \
1972                 defined(WC_ASYNC_ENABLE_SHA384) && !defined(NO_HW_BENCH)
1973             bench_hmac_sha384(1);
1974         #endif
1975         }
1976     #endif
1977     #ifdef WOLFSSL_SHA512
1978         if (bench_all || (bench_mac_algs & BENCH_HMAC_SHA512)) {
1979         #ifndef NO_SW_BENCH
1980             bench_hmac_sha512(0);
1981         #endif
1982         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) && \
1983                 defined(WC_ASYNC_ENABLE_SHA512) && !defined(NO_HW_BENCH)
1984             bench_hmac_sha512(1);
1985         #endif
1986         }
1987     #endif
1988     #ifndef NO_PWDBASED
1989         if (bench_all || (bench_mac_algs & BENCH_PBKDF2)) {
1990             bench_pbkdf2();
1991         }
1992     #endif
1993 #endif /* NO_HMAC */
1994 
1995 #ifdef HAVE_SCRYPT
1996     if (bench_all || (bench_other_algs & BENCH_SCRYPT))
1997         bench_scrypt();
1998 #endif
1999 
2000 #ifndef NO_RSA
2001     #ifdef WOLFSSL_KEY_GEN
2002         if (bench_all || (bench_asym_algs & BENCH_RSA_KEYGEN)) {
2003         #ifndef NO_SW_BENCH
2004             if (((word32)bench_asym_algs == 0xFFFFFFFFU) ||
2005                         (bench_asym_algs & BENCH_RSA_SZ) == 0) {
2006                 bench_rsaKeyGen(0);
2007             }
2008             else {
2009                 bench_rsaKeyGen_size(0, bench_size);
2010             }
2011         #endif
2012         #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA_KEYGEN) \
2013                 && !defined(NO_HW_BENCH)
2014             if (bench_asym_algs & BENCH_RSA_SZ) {
2015                 bench_rsaKeyGen_size(1, bench_size);
2016             }
2017             else {
2018                 bench_rsaKeyGen(1);
2019             }
2020         #endif
2021         }
2022     #endif
2023     if (bench_all || (bench_asym_algs & BENCH_RSA)) {
2024     #ifndef NO_SW_BENCH
2025         bench_rsa(0);
2026     #endif
2027     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
2028         !defined(NO_HW_BENCH)
2029         bench_rsa(1);
2030     #endif
2031     }
2032 
2033     #ifdef WOLFSSL_KEY_GEN
2034     if (bench_asym_algs & BENCH_RSA_SZ) {
2035     #ifndef NO_SW_BENCH
2036         bench_rsa_key(0, bench_size);
2037     #endif
2038     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
2039         !defined(NO_HW_BENCH)
2040         bench_rsa_key(1, bench_size);
2041     #endif
2042     }
2043     #endif
2044 #endif
2045 
2046 #ifndef NO_DH
2047     if (bench_all || (bench_asym_algs & BENCH_DH)) {
2048     #ifndef NO_SW_BENCH
2049         bench_dh(0);
2050     #endif
2051     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH) && \
2052         !defined(NO_HW_BENCH)
2053         bench_dh(1);
2054     #endif
2055     }
2056 #endif
2057 
2058 #ifdef HAVE_ECC
2059     if (bench_all || (bench_asym_algs & BENCH_ECC_MAKEKEY) ||
2060             (bench_asym_algs & BENCH_ECC) ||
2061             (bench_asym_algs & BENCH_ECC_ALL) ||
2062             (bench_asym_algs & BENCH_ECC_ENCRYPT)) {
2063 
2064         if (bench_asym_algs & BENCH_ECC_ALL) {
2065             #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
2066             printf("not supported in FIPS mode (no ending enum value)\n");
2067             #else
2068             int curveId = (int)ECC_SECP192R1;
2069 
2070             /* set make key and encrypt */
2071             bench_asym_algs |= BENCH_ECC_MAKEKEY | BENCH_ECC |
2072                                BENCH_ECC_ENCRYPT;
2073             if (csv_format != 1) {
2074                 printf("\nECC Benchmarks:\n");
2075             }
2076 
2077             do {
2078             #ifdef WOLFCRYPT_HAVE_SAKKE
2079                 /* SAKKE is not useable with ECDH/ECDSA. Run separate test. */
2080                 if (curveId == ECC_SAKKE_1) {
2081                     curveId++;
2082                     continue;
2083                 }
2084             #endif
2085 
2086                 if (wc_ecc_get_curve_size_from_id(curveId) !=
2087                         ECC_BAD_ARG_E) {
2088                     bench_ecc_curve(curveId);
2089                     if (csv_format != 1) {
2090                         printf("\n");
2091                     }
2092                 }
2093                 curveId++;
2094             } while (curveId != (int)ECC_CURVE_MAX);
2095             #endif
2096         }
2097         else if (bench_asym_algs & BENCH_ECC_P256) {
2098             bench_ecc_curve((int)ECC_SECP256R1);
2099         }
2100         else if (bench_asym_algs & BENCH_ECC_P384) {
2101             bench_ecc_curve((int)ECC_SECP384R1);
2102         }
2103         else {
2104             #ifndef NO_ECC256
2105             bench_ecc_curve((int)ECC_SECP256R1);
2106             #endif
2107             #ifdef HAVE_ECC_BRAINPOOL
2108             bench_ecc_curve((int)ECC_BRAINPOOLP256R1);
2109             #endif
2110         }
2111     }
2112 #endif
2113 
2114 #ifdef HAVE_CURVE25519
2115     if (bench_all || (bench_asym_algs & BENCH_CURVE25519_KEYGEN))
2116         bench_curve25519KeyGen();
2117     #ifdef HAVE_CURVE25519_SHARED_SECRET
2118     if (bench_all || (bench_asym_algs & BENCH_CURVE25519_KA))
2119         bench_curve25519KeyAgree();
2120     #endif
2121 #endif
2122 
2123 #ifdef HAVE_ED25519
2124     if (bench_all || (bench_asym_algs & BENCH_ED25519_KEYGEN))
2125         bench_ed25519KeyGen();
2126     if (bench_all || (bench_asym_algs & BENCH_ED25519_SIGN))
2127         bench_ed25519KeySign();
2128 #endif
2129 
2130 #ifdef HAVE_CURVE448
2131     if (bench_all || (bench_asym_algs & BENCH_CURVE448_KEYGEN))
2132         bench_curve448KeyGen();
2133     #ifdef HAVE_CURVE448_SHARED_SECRET
2134     if (bench_all || (bench_asym_algs & BENCH_CURVE448_KA))
2135         bench_curve448KeyAgree();
2136     #endif
2137 #endif
2138 
2139 #ifdef HAVE_ED448
2140     if (bench_all || (bench_asym_algs & BENCH_ED448_KEYGEN))
2141         bench_ed448KeyGen();
2142     if (bench_all || (bench_asym_algs & BENCH_ED448_SIGN))
2143         bench_ed448KeySign();
2144 #endif
2145 
2146 #ifdef WOLFCRYPT_HAVE_ECCSI
2147     #ifdef WOLFCRYPT_ECCSI_KMS
2148         if (bench_all || (bench_asym_algs & BENCH_ECCSI_KEYGEN)) {
2149             bench_eccsiKeyGen();
2150         }
2151         if (bench_all || (bench_asym_algs & BENCH_ECCSI_PAIRGEN)) {
2152             bench_eccsiPairGen();
2153         }
2154     #endif
2155     #ifdef WOLFCRYPT_ECCSI_CLIENT
2156         if (bench_all || (bench_asym_algs & BENCH_ECCSI_VALIDATE)) {
2157             bench_eccsiValidate();
2158         }
2159         if (bench_all || (bench_asym_algs & BENCH_ECCSI)) {
2160             bench_eccsi();
2161         }
2162     #endif
2163 #endif
2164 
2165 #ifdef HAVE_PQC
2166     if (bench_all || (bench_pq_asym_algs & BENCH_FALCON_LEVEL1_SIGN))
2167         bench_falconKeySign(1);
2168     if (bench_all || (bench_pq_asym_algs & BENCH_FALCON_LEVEL5_SIGN))
2169         bench_falconKeySign(5);
2170     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL1_KEYGEN))
2171         bench_pqcKemKeygen(BENCH_KYBER_LEVEL1_KEYGEN);
2172     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL1_ENCAP))
2173         bench_pqcKemEncapDecap(BENCH_KYBER_LEVEL1_ENCAP);
2174     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL3_KEYGEN))
2175         bench_pqcKemKeygen(BENCH_KYBER_LEVEL3_KEYGEN);
2176     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL3_ENCAP))
2177         bench_pqcKemEncapDecap(BENCH_KYBER_LEVEL3_ENCAP);
2178     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL5_KEYGEN))
2179         bench_pqcKemKeygen(BENCH_KYBER_LEVEL5_KEYGEN);
2180     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER_LEVEL5_ENCAP))
2181         bench_pqcKemEncapDecap(BENCH_KYBER_LEVEL5_ENCAP);
2182     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER90S_LEVEL1_KEYGEN))
2183         bench_pqcKemKeygen(BENCH_KYBER90S_LEVEL1_KEYGEN);
2184     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER90S_LEVEL1_ENCAP))
2185         bench_pqcKemEncapDecap(BENCH_KYBER90S_LEVEL1_ENCAP);
2186     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER90S_LEVEL3_KEYGEN))
2187         bench_pqcKemKeygen(BENCH_KYBER90S_LEVEL3_KEYGEN);
2188     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER90S_LEVEL3_ENCAP))
2189         bench_pqcKemEncapDecap(BENCH_KYBER90S_LEVEL3_ENCAP);
2190     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER90S_LEVEL5_KEYGEN))
2191         bench_pqcKemKeygen(BENCH_KYBER90S_LEVEL5_KEYGEN);
2192     if (bench_all || (bench_pq_asym_algs & BENCH_KYBER90S_LEVEL5_ENCAP))
2193         bench_pqcKemEncapDecap(BENCH_KYBER90S_LEVEL5_ENCAP);
2194     if (bench_all || (bench_pq_asym_algs & BENCH_SABER_LEVEL1_KEYGEN))
2195         bench_pqcKemKeygen(BENCH_SABER_LEVEL1_KEYGEN);
2196     if (bench_all || (bench_pq_asym_algs & BENCH_SABER_LEVEL1_ENCAP))
2197         bench_pqcKemEncapDecap(BENCH_SABER_LEVEL1_ENCAP);
2198     if (bench_all || (bench_pq_asym_algs & BENCH_SABER_LEVEL3_KEYGEN))
2199         bench_pqcKemKeygen(BENCH_SABER_LEVEL3_KEYGEN);
2200     if (bench_all || (bench_pq_asym_algs & BENCH_SABER_LEVEL3_ENCAP))
2201         bench_pqcKemEncapDecap(BENCH_SABER_LEVEL3_ENCAP);
2202     if (bench_all || (bench_pq_asym_algs & BENCH_SABER_LEVEL5_KEYGEN))
2203         bench_pqcKemKeygen(BENCH_SABER_LEVEL5_KEYGEN);
2204     if (bench_all || (bench_pq_asym_algs & BENCH_SABER_LEVEL5_ENCAP))
2205         bench_pqcKemEncapDecap(BENCH_SABER_LEVEL5_ENCAP);
2206     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHPS_LEVEL1_KEYGEN))
2207         bench_pqcKemKeygen(BENCH_NTRUHPS_LEVEL1_KEYGEN);
2208     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHPS_LEVEL1_ENCAP))
2209         bench_pqcKemEncapDecap(BENCH_NTRUHPS_LEVEL1_ENCAP);
2210     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHPS_LEVEL3_KEYGEN))
2211         bench_pqcKemKeygen(BENCH_NTRUHPS_LEVEL3_KEYGEN);
2212     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHPS_LEVEL3_ENCAP))
2213         bench_pqcKemEncapDecap(BENCH_NTRUHPS_LEVEL3_ENCAP);
2214     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHPS_LEVEL5_KEYGEN))
2215         bench_pqcKemKeygen(BENCH_NTRUHPS_LEVEL5_KEYGEN);
2216     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHPS_LEVEL5_ENCAP))
2217         bench_pqcKemEncapDecap(BENCH_NTRUHPS_LEVEL5_ENCAP);
2218     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHRSS_LEVEL3_KEYGEN))
2219         bench_pqcKemKeygen(BENCH_NTRUHRSS_LEVEL3_KEYGEN);
2220     if (bench_all || (bench_pq_asym_algs & BENCH_NTRUHRSS_LEVEL3_ENCAP))
2221         bench_pqcKemEncapDecap(BENCH_NTRUHRSS_LEVEL3_ENCAP);
2222 #endif
2223 
2224 #ifdef WOLFCRYPT_HAVE_SAKKE
2225     #ifdef WOLFCRYPT_SAKKE_KMS
2226         if (bench_all || (bench_asym_algs & BENCH_SAKKE_KEYGEN)) {
2227             bench_sakkeKeyGen();
2228         }
2229         if (bench_all || (bench_asym_algs & BENCH_SAKKE_RSKGEN)) {
2230             bench_sakkeRskGen();
2231         }
2232     #endif
2233     #ifdef WOLFCRYPT_SAKKE_CLIENT
2234         if (bench_all || (bench_asym_algs & BENCH_SAKKE_VALIDATE)) {
2235             bench_sakkeValidate();
2236         }
2237         if (bench_all || (bench_asym_algs & BENCH_SAKKE)) {
2238             bench_sakke();
2239         }
2240     #endif
2241 #endif
2242 
2243 exit:
2244     /* free benchmark buffers */
2245     XFREE(bench_plain, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
2246     XFREE(bench_cipher, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
2247 #ifdef WOLFSSL_ASYNC_CRYPT
2248     XFREE(bench_key, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
2249     XFREE(bench_iv, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
2250 #endif
2251 
2252 #if defined(HAVE_LOCAL_RNG)
2253     wc_FreeRng(&gRng);
2254 #endif
2255 
2256 /* cleanup the thread if fixed point cache is enabled and have thread local */
2257 #if defined(HAVE_THREAD_LS) && defined(HAVE_ECC) && defined(FP_ECC)
2258     wc_ecc_fp_free();
2259 #endif
2260 
2261     (void)bench_cipher_algs;
2262     (void)bench_digest_algs;
2263     (void)bench_mac_algs;
2264     (void)bench_asym_algs;
2265     (void)bench_other_algs;
2266 
2267     return NULL;
2268 }
2269 
benchmark_init(void)2270 int benchmark_init(void)
2271 {
2272     int ret = 0;
2273 
2274     benchmark_static_init();
2275 
2276 #ifdef WOLFSSL_STATIC_MEMORY
2277     ret = wc_LoadStaticMemory(&HEAP_HINT, gBenchMemory, sizeof(gBenchMemory),
2278                                                             WOLFMEM_GENERAL, 1);
2279     if (ret != 0) {
2280         printf("unable to load static memory %d\n", ret);
2281     }
2282 #endif /* WOLFSSL_STATIC_MEMORY */
2283 
2284     if ((ret = wolfCrypt_Init()) != 0) {
2285         printf("wolfCrypt_Init failed %d\n", ret);
2286         return EXIT_FAILURE;
2287     }
2288 #ifdef WC_RNG_SEED_CB
2289     wc_SetSeed_Cb(wc_GenerateSeed);
2290 #endif
2291 
2292     bench_stats_init();
2293 
2294 #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND)
2295     wolfSSL_Debugging_ON();
2296 #endif
2297 
2298     if (csv_format == 1) {
2299         printf("wolfCrypt Benchmark (block bytes %d, min %.1f sec each)\n",
2300         (int)BENCH_SIZE, BENCH_MIN_RUNTIME_SEC);
2301         printf("This format allows you to easily copy the output to a csv file.");
2302         printf("\n\nSymmetric Ciphers:\n\n");
2303         printf("Algorithm,MB/s,Cycles per byte,\n");
2304     } else {
2305         printf("wolfCrypt Benchmark (block bytes %d, min %.1f sec each)\n",
2306         (int)BENCH_SIZE, BENCH_MIN_RUNTIME_SEC);
2307     }
2308 
2309 #ifdef HAVE_WNR
2310     ret = wc_InitNetRandom(wnrConfigFile, NULL, 5000);
2311     if (ret != 0) {
2312         printf("Whitewood netRandom config init failed %d\n", ret);
2313     }
2314 #endif /* HAVE_WNR */
2315 
2316     return ret;
2317 }
2318 
benchmark_free(void)2319 int benchmark_free(void)
2320 {
2321     int ret;
2322 
2323 #ifndef HAVE_RENESAS_SYNC
2324     if (gPrintStats || devId != INVALID_DEVID) {
2325         bench_stats_print();
2326     }
2327 #endif
2328 
2329     bench_stats_free();
2330 
2331 #ifdef WOLF_CRYPTO_CB
2332 #ifdef HAVE_INTEL_QA_SYNC
2333     wc_CryptoCb_CleanupIntelQa(&devId);
2334 #endif
2335 #ifdef HAVE_CAVIUM_OCTEON_SYNC
2336     wc_CryptoCb_CleanupOcteon(&devId);
2337 #endif
2338 #ifdef HAVE_RENESAS_SYNC
2339     wc_CryptoCb_CleanupRenesasCmn(&devId);
2340 #endif
2341 #endif
2342 
2343 #ifdef WOLFSSL_ASYNC_CRYPT
2344     /* free event queue */
2345     wolfEventQueue_Free(&eventQueue);
2346 
2347     /* close device */
2348     wolfAsync_DevClose(&devId);
2349 #endif
2350 
2351 #ifdef HAVE_WNR
2352     ret = wc_FreeNetRandom();
2353     if (ret < 0) {
2354         printf("Failed to free netRandom context %d\n", ret);
2355     }
2356 #endif
2357 
2358     if ((ret = wolfCrypt_Cleanup()) != 0) {
2359         printf("error %d with wolfCrypt_Cleanup\n", ret);
2360     }
2361 
2362     return ret;
2363 }
2364 
2365 /* so embedded projects can pull in tests on their own */
2366 #ifdef HAVE_STACK_SIZE
benchmark_test(void * args)2367 THREAD_RETURN WOLFSSL_THREAD benchmark_test(void* args)
2368 #else
2369 int benchmark_test(void *args)
2370 #endif
2371 {
2372     int ret;
2373 
2374     (void)args;
2375 
2376     printf("------------------------------------------------------------------------------\n");
2377     printf(" wolfSSL version %s\n", LIBWOLFSSL_VERSION_STRING);
2378     printf("------------------------------------------------------------------------------\n");
2379 
2380 #ifdef HAVE_FIPS
2381     wolfCrypt_SetCb_fips(myFipsCb);
2382 #endif
2383 
2384     ret = benchmark_init();
2385     if (ret != 0)
2386         EXIT_TEST(ret);
2387 
2388 #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING)
2389 {
2390     int i;
2391 
2392     if (g_threadCount == 0) {
2393     #ifdef WC_ASYNC_BENCH_THREAD_COUNT
2394         g_threadCount = WC_ASYNC_BENCH_THREAD_COUNT;
2395     #else
2396         g_threadCount = wc_AsyncGetNumberOfCpus();
2397         if (g_threadCount > 0) {
2398             g_threadCount /= 2; /* use physical core count */
2399         }
2400     #endif
2401     }
2402     if (g_threadCount <= 0) {
2403         g_threadCount = 1;
2404     }
2405 
2406     printf("CPUs: %d\n", g_threadCount);
2407 
2408     g_threadData = (ThreadData*)XMALLOC(sizeof(ThreadData) * g_threadCount,
2409         HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
2410     if (g_threadData == NULL) {
2411         printf("Thread data alloc failed!\n");
2412         EXIT_TEST(EXIT_FAILURE);
2413     }
2414 
2415     /* Create threads */
2416     for (i = 0; i < g_threadCount; i++) {
2417         ret = wc_AsyncThreadCreate(&g_threadData[i].thread_id,
2418             benchmarks_do, &g_threadData[i]);
2419         if (ret != 0) {
2420             printf("Error creating benchmark thread %d\n", ret);
2421             EXIT_TEST(EXIT_FAILURE);
2422         }
2423     }
2424 
2425     /* Start threads */
2426     for (i = 0; i < g_threadCount; i++) {
2427         wc_AsyncThreadJoin(&g_threadData[i].thread_id);
2428     }
2429 
2430     XFREE(g_threadData, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
2431 }
2432 #else
2433     benchmarks_do(NULL);
2434 #endif
2435 
2436     printf("Benchmark complete\n");
2437 
2438     ret = benchmark_free();
2439 
2440     EXIT_TEST(ret);
2441 }
2442 
2443 
2444 #ifndef WC_NO_RNG
bench_rng(void)2445 void bench_rng(void)
2446 {
2447     int    ret, i, count;
2448     double start;
2449     long   pos, len, remain;
2450     WC_RNG myrng;
2451 
2452 #ifndef HAVE_FIPS
2453     ret = wc_InitRng_ex(&myrng, HEAP_HINT, devId);
2454 #else
2455     ret = wc_InitRng(&myrng);
2456 #endif
2457     if (ret < 0) {
2458         printf("InitRNG failed %d\n", ret);
2459         return;
2460     }
2461 
2462     bench_stats_start(&count, &start);
2463     do {
2464         for (i = 0; i < numBlocks; i++) {
2465             /* Split request to handle large RNG request */
2466             pos = 0;
2467             remain = (int)BENCH_SIZE;
2468             while (remain > 0) {
2469                 len = remain;
2470                 if (len > RNG_MAX_BLOCK_LEN)
2471                     len = RNG_MAX_BLOCK_LEN;
2472                 ret = wc_RNG_GenerateBlock(&myrng, &bench_plain[pos], (word32)len);
2473                 if (ret < 0)
2474                     goto exit_rng;
2475 
2476                 remain -= len;
2477                 pos += len;
2478             }
2479         }
2480         count += i;
2481     } while (bench_stats_sym_check(start));
2482 exit_rng:
2483     bench_stats_sym_finish("RNG", 0, count, bench_size, start, ret);
2484 
2485     wc_FreeRng(&myrng);
2486 }
2487 #endif /* WC_NO_RNG */
2488 
2489 
2490 #ifndef NO_AES
2491 
2492 #ifdef HAVE_AES_CBC
bench_aescbc_internal(int doAsync,const byte * key,word32 keySz,const byte * iv,const char * encLabel,const char * decLabel)2493 static void bench_aescbc_internal(int doAsync, const byte* key, word32 keySz,
2494                                   const byte* iv, const char* encLabel,
2495                                   const char* decLabel)
2496 {
2497     int    ret = 0, i, count = 0, times, pending = 0;
2498     Aes    enc[BENCH_MAX_PENDING];
2499     double start;
2500 
2501     /* clear for done cleanup */
2502     XMEMSET(enc, 0, sizeof(enc));
2503 
2504     /* init keys */
2505     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2506         if ((ret = wc_AesInit(&enc[i], HEAP_HINT,
2507                                 doAsync ? devId : INVALID_DEVID)) != 0) {
2508             printf("AesInit failed, ret = %d\n", ret);
2509             goto exit;
2510         }
2511 
2512         ret = wc_AesSetKey(&enc[i], key, keySz, iv, AES_ENCRYPTION);
2513         if (ret != 0) {
2514             printf("AesSetKey failed, ret = %d\n", ret);
2515             goto exit;
2516         }
2517     }
2518 
2519     bench_stats_start(&count, &start);
2520     do {
2521         for (times = 0; times < numBlocks || pending > 0; ) {
2522             bench_async_poll(&pending);
2523 
2524             /* while free pending slots in queue, submit ops */
2525             for (i = 0; i < BENCH_MAX_PENDING; i++) {
2526                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
2527                     ret = wc_AesCbcEncrypt(&enc[i], bench_plain, bench_cipher,
2528                         BENCH_SIZE);
2529                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
2530                         goto exit_aes_enc;
2531                     }
2532                 }
2533             } /* for i */
2534         } /* for times */
2535         count += times;
2536     } while (bench_stats_sym_check(start));
2537 exit_aes_enc:
2538     bench_stats_sym_finish(encLabel, doAsync, count, bench_size, start, ret);
2539 
2540     if (ret < 0) {
2541         goto exit;
2542     }
2543 
2544 #ifdef HAVE_AES_DECRYPT
2545     /* init keys */
2546     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2547         ret = wc_AesSetKey(&enc[i], key, keySz, iv, AES_DECRYPTION);
2548         if (ret != 0) {
2549             printf("AesSetKey failed, ret = %d\n", ret);
2550             goto exit;
2551         }
2552     }
2553 
2554     bench_stats_start(&count, &start);
2555     do {
2556         for (times = 0; times < numBlocks || pending > 0; ) {
2557             bench_async_poll(&pending);
2558 
2559             /* while free pending slots in queue, submit ops */
2560             for (i = 0; i < BENCH_MAX_PENDING; i++) {
2561                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
2562                     ret = wc_AesCbcDecrypt(&enc[i], bench_plain, bench_cipher,
2563                         BENCH_SIZE);
2564                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
2565                         goto exit_aes_dec;
2566                     }
2567                 }
2568             } /* for i */
2569         } /* for times */
2570         count += times;
2571     } while (bench_stats_sym_check(start));
2572 exit_aes_dec:
2573     bench_stats_sym_finish(decLabel, doAsync, count, bench_size, start, ret);
2574 
2575 #endif /* HAVE_AES_DECRYPT */
2576 
2577     (void)decLabel;
2578 exit:
2579 
2580     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2581         wc_AesFree(&enc[i]);
2582     }
2583 }
2584 
bench_aescbc(int doAsync)2585 void bench_aescbc(int doAsync)
2586 {
2587 #ifdef WOLFSSL_AES_128
2588     bench_aescbc_internal(doAsync, bench_key, 16, bench_iv,
2589                  "AES-128-CBC-enc", "AES-128-CBC-dec");
2590 #endif
2591 #ifdef WOLFSSL_AES_192
2592     bench_aescbc_internal(doAsync, bench_key, 24, bench_iv,
2593                  "AES-192-CBC-enc", "AES-192-CBC-dec");
2594 #endif
2595 #ifdef WOLFSSL_AES_256
2596     bench_aescbc_internal(doAsync, bench_key, 32, bench_iv,
2597                  "AES-256-CBC-enc", "AES-256-CBC-dec");
2598 #endif
2599 }
2600 
2601 #endif /* HAVE_AES_CBC */
2602 
2603 #ifdef HAVE_AESGCM
bench_aesgcm_internal(int doAsync,const byte * key,word32 keySz,const byte * iv,word32 ivSz,const char * encLabel,const char * decLabel)2604 static void bench_aesgcm_internal(int doAsync, const byte* key, word32 keySz,
2605                                   const byte* iv, word32 ivSz,
2606                                   const char* encLabel, const char* decLabel)
2607 {
2608     int    ret = 0, i, count = 0, times, pending = 0;
2609     Aes    enc[BENCH_MAX_PENDING];
2610 #ifdef HAVE_AES_DECRYPT
2611     Aes    dec[BENCH_MAX_PENDING];
2612 #endif
2613     double start;
2614 
2615     WC_DECLARE_VAR(bench_additional, byte, AES_AUTH_ADD_SZ, HEAP_HINT);
2616     WC_DECLARE_VAR(bench_tag, byte, AES_AUTH_TAG_SZ, HEAP_HINT);
2617 #ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
2618     if (bench_additional == NULL || bench_tag == NULL) {
2619         printf("bench_aesgcm_internal malloc failed\n");
2620         goto exit;
2621     }
2622 #endif
2623 
2624     /* clear for done cleanup */
2625     XMEMSET(enc, 0, sizeof(enc));
2626 #ifdef HAVE_AES_DECRYPT
2627     XMEMSET(dec, 0, sizeof(dec));
2628 #endif
2629 #ifdef WOLFSSL_ASYNC_CRYPT
2630     if (bench_additional)
2631 #endif
2632         XMEMSET(bench_additional, 0, AES_AUTH_ADD_SZ);
2633 #ifdef WOLFSSL_ASYNC_CRYPT
2634     if (bench_tag)
2635 #endif
2636         XMEMSET(bench_tag, 0, AES_AUTH_TAG_SZ);
2637 
2638     /* init keys */
2639     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2640         if ((ret = wc_AesInit(&enc[i], HEAP_HINT,
2641                         doAsync ? devId : INVALID_DEVID)) != 0) {
2642             printf("AesInit failed, ret = %d\n", ret);
2643             goto exit;
2644         }
2645 
2646         ret = wc_AesGcmSetKey(&enc[i], key, keySz);
2647         if (ret != 0) {
2648             printf("AesGcmSetKey failed, ret = %d\n", ret);
2649             goto exit;
2650         }
2651     }
2652 
2653     /* GCM uses same routine in backend for both encrypt and decrypt */
2654     bench_stats_start(&count, &start);
2655     do {
2656         for (times = 0; times < numBlocks || pending > 0; ) {
2657             bench_async_poll(&pending);
2658 
2659             /* while free pending slots in queue, submit ops */
2660             for (i = 0; i < BENCH_MAX_PENDING; i++) {
2661                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
2662 #ifndef BENCHMARK_AESGCM_STREAM
2663                     ret = wc_AesGcmEncrypt(&enc[i], bench_cipher,
2664                         bench_plain, BENCH_SIZE,
2665                         iv, ivSz, bench_tag, AES_AUTH_TAG_SZ,
2666                         bench_additional, aesAuthAddSz);
2667 #else
2668                     ret = wc_AesGcmEncryptInit(&enc[i], NULL, 0, iv, ivSz);
2669                     if (ret == 0) {
2670                         ret = wc_AesGcmEncryptUpdate(&enc[i], bench_cipher,
2671                             bench_plain, BENCH_SIZE, bench_additional,
2672                             aesAuthAddSz);
2673                     }
2674                     if (ret == 0) {
2675                         ret = wc_AesGcmEncryptFinal(&enc[i], bench_tag,
2676                             AES_AUTH_TAG_SZ);
2677                     }
2678 #endif
2679                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
2680                         goto exit_aes_gcm;
2681                     }
2682                 }
2683             } /* for i */
2684         } /* for times */
2685         count += times;
2686     } while (bench_stats_sym_check(start));
2687 exit_aes_gcm:
2688     bench_stats_sym_finish(encLabel, doAsync, count, bench_size, start, ret);
2689 
2690 #ifdef HAVE_AES_DECRYPT
2691     /* init keys */
2692     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2693         if ((ret = wc_AesInit(&dec[i], HEAP_HINT,
2694                         doAsync ? devId : INVALID_DEVID)) != 0) {
2695             printf("AesInit failed, ret = %d\n", ret);
2696             goto exit;
2697         }
2698 
2699         ret = wc_AesGcmSetKey(&dec[i], key, keySz);
2700         if (ret != 0) {
2701             printf("AesGcmSetKey failed, ret = %d\n", ret);
2702             goto exit;
2703         }
2704     }
2705 
2706     bench_stats_start(&count, &start);
2707     do {
2708         for (times = 0; times < numBlocks || pending > 0; ) {
2709             bench_async_poll(&pending);
2710 
2711             /* while free pending slots in queue, submit ops */
2712             for (i = 0; i < BENCH_MAX_PENDING; i++) {
2713                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&dec[i]), 0, &times, numBlocks, &pending)) {
2714 #ifndef BENCHMARK_AESGCM_STREAM
2715                     ret = wc_AesGcmDecrypt(&dec[i], bench_plain,
2716                         bench_cipher, BENCH_SIZE,
2717                         iv, ivSz, bench_tag, AES_AUTH_TAG_SZ,
2718                         bench_additional, aesAuthAddSz);
2719 #else
2720                     ret = wc_AesGcmDecryptInit(&enc[i], NULL, 0, iv, ivSz);
2721                     if (ret == 0) {
2722                         ret = wc_AesGcmDecryptUpdate(&enc[i], bench_plain,
2723                             bench_cipher, BENCH_SIZE, bench_additional,
2724                             aesAuthAddSz);
2725                     }
2726                     if (ret == 0) {
2727                         ret = wc_AesGcmDecryptFinal(&enc[i], bench_tag,
2728                             AES_AUTH_TAG_SZ);
2729                     }
2730 #endif
2731                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&dec[i]), 0, &times, &pending)) {
2732                         goto exit_aes_gcm_dec;
2733                     }
2734                 }
2735             } /* for i */
2736         } /* for times */
2737         count += times;
2738     } while (bench_stats_sym_check(start));
2739 exit_aes_gcm_dec:
2740     bench_stats_sym_finish(decLabel, doAsync, count, bench_size, start, ret);
2741 #endif /* HAVE_AES_DECRYPT */
2742 
2743     (void)decLabel;
2744 
2745 exit:
2746 
2747     if (ret < 0) {
2748         printf("bench_aesgcm failed: %d\n", ret);
2749     }
2750 #ifdef HAVE_AES_DECRYPT
2751     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2752         wc_AesFree(&dec[i]);
2753     }
2754 #endif
2755     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2756         wc_AesFree(&enc[i]);
2757     }
2758 
2759     WC_FREE_VAR(bench_additional, HEAP_HINT);
2760     WC_FREE_VAR(bench_tag, HEAP_HINT);
2761 }
2762 
bench_aesgcm(int doAsync)2763 void bench_aesgcm(int doAsync)
2764 {
2765 #if defined(WOLFSSL_AES_128) && !defined(WOLFSSL_AFALG_XILINX_AES) \
2766         && !defined(WOLFSSL_XILINX_CRYPT)
2767     bench_aesgcm_internal(doAsync, bench_key, 16, bench_iv, 12,
2768                           "AES-128-GCM-enc", "AES-128-GCM-dec");
2769 #endif
2770 #if defined(WOLFSSL_AES_192) && !defined(WOLFSSL_AFALG_XILINX_AES) \
2771         && !defined(WOLFSSL_XILINX_CRYPT)
2772     bench_aesgcm_internal(doAsync, bench_key, 24, bench_iv, 12,
2773                           "AES-192-GCM-enc", "AES-192-GCM-dec");
2774 #endif
2775 #ifdef WOLFSSL_AES_256
2776     bench_aesgcm_internal(doAsync, bench_key, 32, bench_iv, 12,
2777                           "AES-256-GCM-enc", "AES-256-GCM-dec");
2778 #endif
2779 }
2780 
2781 /* GMAC */
bench_gmac(void)2782 void bench_gmac(void)
2783 {
2784     int ret, count = 0;
2785     Gmac gmac;
2786     double start;
2787     byte tag[AES_AUTH_TAG_SZ];
2788 
2789     /* determine GCM GHASH method */
2790 #ifdef GCM_SMALL
2791     const char* gmacStr = "GMAC Small";
2792 #elif defined(GCM_TABLE)
2793     const char* gmacStr = "GMAC Table";
2794 #elif defined(GCM_TABLE_4BIT)
2795     const char* gmacStr = "GMAC Table 4-bit";
2796 #elif defined(GCM_WORD32)
2797     const char* gmacStr = "GMAC Word32";
2798 #else
2799     const char* gmacStr = "GMAC Default";
2800 #endif
2801 
2802     /* init keys */
2803     XMEMSET(bench_plain, 0, bench_size);
2804     XMEMSET(tag, 0, sizeof(tag));
2805     XMEMSET(&gmac, 0, sizeof(Gmac)); /* clear context */
2806     (void)wc_AesInit((Aes*)&gmac, HEAP_HINT, INVALID_DEVID);
2807     wc_GmacSetKey(&gmac, bench_key, 16);
2808 
2809     bench_stats_start(&count, &start);
2810     do {
2811         ret = wc_GmacUpdate(&gmac, bench_iv, 12, bench_plain, bench_size,
2812             tag, sizeof(tag));
2813 
2814         count++;
2815     } while (bench_stats_sym_check(start));
2816     wc_AesFree((Aes*)&gmac);
2817 
2818     bench_stats_sym_finish(gmacStr, 0, count, bench_size, start, ret);
2819 }
2820 
2821 #endif /* HAVE_AESGCM */
2822 
2823 
2824 #ifdef WOLFSSL_AES_DIRECT
bench_aesecb_internal(int doAsync,const byte * key,word32 keySz,const char * encLabel,const char * decLabel)2825 static void bench_aesecb_internal(int doAsync, const byte* key, word32 keySz,
2826                                   const char* encLabel, const char* decLabel)
2827 {
2828     int    ret = 0, i, count = 0, times, pending = 0;
2829     Aes    enc[BENCH_MAX_PENDING];
2830     double start;
2831 
2832     /* clear for done cleanup */
2833     XMEMSET(enc, 0, sizeof(enc));
2834 
2835     /* init keys */
2836     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2837         if ((ret = wc_AesInit(&enc[i], HEAP_HINT,
2838                                 doAsync ? devId : INVALID_DEVID)) != 0) {
2839             printf("AesInit failed, ret = %d\n", ret);
2840             goto exit;
2841         }
2842 
2843         ret = wc_AesSetKey(&enc[i], key, keySz, bench_iv, AES_ENCRYPTION);
2844         if (ret != 0) {
2845             printf("AesSetKey failed, ret = %d\n", ret);
2846             goto exit;
2847         }
2848     }
2849 
2850     bench_stats_start(&count, &start);
2851     do {
2852         for (times = 0; times < numBlocks || pending > 0; ) {
2853             bench_async_poll(&pending);
2854 
2855             /* while free pending slots in queue, submit ops */
2856             for (i = 0; i < BENCH_MAX_PENDING; i++) {
2857                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
2858                     wc_AesEncryptDirect(&enc[i], bench_cipher, bench_plain);
2859                     ret = 0;
2860                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
2861                         goto exit_aes_enc;
2862                     }
2863                 }
2864             } /* for i */
2865         } /* for times */
2866         count += times;
2867     } while (bench_stats_sym_check(start));
2868 exit_aes_enc:
2869     bench_stats_sym_finish(encLabel, doAsync, count, AES_BLOCK_SIZE,
2870                            start, ret);
2871 
2872 #ifdef HAVE_AES_DECRYPT
2873     /* init keys */
2874     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2875         ret = wc_AesSetKey(&enc[i], key, keySz, bench_iv, AES_DECRYPTION);
2876         if (ret != 0) {
2877             printf("AesSetKey failed, ret = %d\n", ret);
2878             goto exit;
2879         }
2880     }
2881 
2882     bench_stats_start(&count, &start);
2883     do {
2884         for (times = 0; times < numBlocks || pending > 0; ) {
2885             bench_async_poll(&pending);
2886 
2887             /* while free pending slots in queue, submit ops */
2888             for (i = 0; i < BENCH_MAX_PENDING; i++) {
2889                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
2890                     wc_AesDecryptDirect(&enc[i], bench_plain,
2891                                               bench_cipher);
2892                     ret = 0;
2893                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
2894                         goto exit_aes_dec;
2895                     }
2896                 }
2897             } /* for i */
2898         } /* for times */
2899         count += times;
2900     } while (bench_stats_sym_check(start));
2901 exit_aes_dec:
2902     bench_stats_sym_finish(decLabel, doAsync, count, AES_BLOCK_SIZE,
2903                            start, ret);
2904 
2905 #endif /* HAVE_AES_DECRYPT */
2906 
2907 exit:
2908 
2909     for (i = 0; i < BENCH_MAX_PENDING; i++) {
2910         wc_AesFree(&enc[i]);
2911     }
2912 }
2913 
bench_aesecb(int doAsync)2914 void bench_aesecb(int doAsync)
2915 {
2916 #ifdef WOLFSSL_AES_128
2917     bench_aesecb_internal(doAsync, bench_key, 16,
2918                  "AES-128-ECB-enc", "AES-128-ECB-dec");
2919 #endif
2920 #ifdef WOLFSSL_AES_192
2921     bench_aesecb_internal(doAsync, bench_key, 24,
2922                  "AES-192-ECB-enc", "AES-192-ECB-dec");
2923 #endif
2924 #ifdef WOLFSSL_AES_256
2925     bench_aesecb_internal(doAsync, bench_key, 32,
2926                  "AES-256-ECB-enc", "AES-256-ECB-dec");
2927 #endif
2928 }
2929 #endif /* WOLFSSL_AES_DIRECT */
2930 
2931 #ifdef WOLFSSL_AES_CFB
bench_aescfb_internal(const byte * key,word32 keySz,const byte * iv,const char * label)2932 static void bench_aescfb_internal(const byte* key, word32 keySz, const byte* iv,
2933                                   const char* label)
2934 {
2935     Aes    enc;
2936     double start;
2937     int    i, ret, count;
2938 
2939     ret = wc_AesSetKey(&enc, key, keySz, iv, AES_ENCRYPTION);
2940     if (ret != 0) {
2941         printf("AesSetKey failed, ret = %d\n", ret);
2942         return;
2943     }
2944 
2945     bench_stats_start(&count, &start);
2946     do {
2947         for (i = 0; i < numBlocks; i++) {
2948             if((ret = wc_AesCfbEncrypt(&enc, bench_plain, bench_cipher,
2949                             BENCH_SIZE)) != 0) {
2950                 printf("wc_AesCfbEncrypt failed, ret = %d\n", ret);
2951                 return;
2952             }
2953         }
2954         count += i;
2955     } while (bench_stats_sym_check(start));
2956     bench_stats_sym_finish(label, 0, count, bench_size, start, ret);
2957 }
2958 
bench_aescfb(void)2959 void bench_aescfb(void)
2960 {
2961 #ifdef WOLFSSL_AES_128
2962     bench_aescfb_internal(bench_key, 16, bench_iv, "AES-128-CFB");
2963 #endif
2964 #ifdef WOLFSSL_AES_192
2965     bench_aescfb_internal(bench_key, 24, bench_iv, "AES-192-CFB");
2966 #endif
2967 #ifdef WOLFSSL_AES_256
2968     bench_aescfb_internal(bench_key, 32, bench_iv, "AES-256-CFB");
2969 #endif
2970 }
2971 #endif /* WOLFSSL_AES_CFB */
2972 
2973 
2974 #ifdef WOLFSSL_AES_OFB
bench_aesofb_internal(const byte * key,word32 keySz,const byte * iv,const char * label)2975 static void bench_aesofb_internal(const byte* key, word32 keySz, const byte* iv,
2976                                   const char* label)
2977 {
2978     Aes    enc;
2979     double start;
2980     int    i, ret, count;
2981 
2982     ret = wc_AesSetKey(&enc, key, keySz, iv, AES_ENCRYPTION);
2983     if (ret != 0) {
2984         printf("AesSetKey failed, ret = %d\n", ret);
2985         return;
2986     }
2987 
2988     bench_stats_start(&count, &start);
2989     do {
2990         for (i = 0; i < numBlocks; i++) {
2991             if((ret = wc_AesOfbEncrypt(&enc, bench_plain, bench_cipher,
2992                             BENCH_SIZE)) != 0) {
2993                 printf("wc_AesCfbEncrypt failed, ret = %d\n", ret);
2994                 return;
2995             }
2996         }
2997         count += i;
2998     } while (bench_stats_sym_check(start));
2999     bench_stats_sym_finish(label, 0, count, bench_size, start, ret);
3000 }
3001 
bench_aesofb(void)3002 void bench_aesofb(void)
3003 {
3004 #ifdef WOLFSSL_AES_128
3005     bench_aesofb_internal(bench_key, 16, bench_iv, "AES-128-OFB");
3006 #endif
3007 #ifdef WOLFSSL_AES_192
3008     bench_aesofb_internal(bench_key, 24, bench_iv, "AES-192-OFB");
3009 #endif
3010 #ifdef WOLFSSL_AES_256
3011     bench_aesofb_internal(bench_key, 32, bench_iv, "AES-256-OFB");
3012 #endif
3013 }
3014 #endif /* WOLFSSL_AES_CFB */
3015 
3016 
3017 #ifdef WOLFSSL_AES_XTS
bench_aesxts(void)3018 void bench_aesxts(void)
3019 {
3020     XtsAes aes;
3021     double start;
3022     int    i, count, ret;
3023 
3024     static unsigned char k1[] = {
3025         0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35,
3026         0x3b, 0x2c, 0x34, 0x38, 0x76, 0x08, 0x17, 0x62,
3027         0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18,
3028         0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f
3029     };
3030 
3031     static unsigned char i1[] = {
3032         0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6,
3033         0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5
3034     };
3035 
3036     ret = wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_ENCRYPTION,
3037             HEAP_HINT, devId);
3038     if (ret != 0) {
3039         printf("wc_AesXtsSetKey failed, ret = %d\n", ret);
3040         return;
3041     }
3042 
3043     bench_stats_start(&count, &start);
3044     do {
3045         for (i = 0; i < numBlocks; i++) {
3046             if ((ret = wc_AesXtsEncrypt(&aes, bench_plain, bench_cipher,
3047                             BENCH_SIZE, i1, sizeof(i1))) != 0) {
3048                 printf("wc_AesXtsEncrypt failed, ret = %d\n", ret);
3049                 return;
3050             }
3051         }
3052         count += i;
3053     } while (bench_stats_sym_check(start));
3054     bench_stats_sym_finish("AES-XTS-enc", 0, count, bench_size, start, ret);
3055     wc_AesXtsFree(&aes);
3056 
3057     /* decryption benchmark */
3058     ret = wc_AesXtsSetKey(&aes, k1, sizeof(k1), AES_DECRYPTION,
3059             HEAP_HINT, devId);
3060     if (ret != 0) {
3061         printf("wc_AesXtsSetKey failed, ret = %d\n", ret);
3062         return;
3063     }
3064 
3065     bench_stats_start(&count, &start);
3066     do {
3067         for (i = 0; i < numBlocks; i++) {
3068             if ((ret = wc_AesXtsDecrypt(&aes, bench_plain, bench_cipher,
3069                             BENCH_SIZE, i1, sizeof(i1))) != 0) {
3070                 printf("wc_AesXtsDecrypt failed, ret = %d\n", ret);
3071                 return;
3072             }
3073         }
3074         count += i;
3075     } while (bench_stats_sym_check(start));
3076     bench_stats_sym_finish("AES-XTS-dec", 0, count, bench_size, start, ret);
3077     wc_AesXtsFree(&aes);
3078 }
3079 #endif /* WOLFSSL_AES_XTS */
3080 
3081 
3082 #ifdef WOLFSSL_AES_COUNTER
bench_aesctr_internal(const byte * key,word32 keySz,const byte * iv,const char * label)3083 static void bench_aesctr_internal(const byte* key, word32 keySz, const byte* iv,
3084                                   const char* label)
3085 {
3086     Aes    enc;
3087     double start;
3088     int    i, count, ret = 0;
3089 
3090     wc_AesSetKeyDirect(&enc, key, keySz, iv, AES_ENCRYPTION);
3091 
3092     bench_stats_start(&count, &start);
3093     do {
3094         for (i = 0; i < numBlocks; i++) {
3095             if((ret = wc_AesCtrEncrypt(&enc, bench_plain, bench_cipher, BENCH_SIZE)) != 0) {
3096                 printf("wc_AesCtrEncrypt failed, ret = %d\n", ret);
3097                 return;
3098             }
3099         }
3100         count += i;
3101     } while (bench_stats_sym_check(start));
3102     bench_stats_sym_finish(label, 0, count, bench_size, start, ret);
3103 }
3104 
bench_aesctr(void)3105 void bench_aesctr(void)
3106 {
3107 #ifdef WOLFSSL_AES_128
3108     bench_aesctr_internal(bench_key, 16, bench_iv, "AES-128-CTR");
3109 #endif
3110 #ifdef WOLFSSL_AES_192
3111     bench_aesctr_internal(bench_key, 24, bench_iv, "AES-192-CTR");
3112 #endif
3113 #ifdef WOLFSSL_AES_256
3114     bench_aesctr_internal(bench_key, 32, bench_iv, "AES-256-CTR");
3115 #endif
3116 }
3117 #endif /* WOLFSSL_AES_COUNTER */
3118 
3119 
3120 #ifdef HAVE_AESCCM
bench_aesccm(void)3121 void bench_aesccm(void)
3122 {
3123     Aes    enc;
3124     double start;
3125     int    ret, i, count;
3126 
3127     WC_DECLARE_VAR(bench_additional, byte, AES_AUTH_ADD_SZ, HEAP_HINT);
3128     WC_DECLARE_VAR(bench_tag, byte, AES_AUTH_TAG_SZ, HEAP_HINT);
3129 
3130 #ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
3131     if (bench_additional == NULL || bench_tag == NULL) {
3132         printf("bench_aesccm malloc failed\n");
3133         goto exit;
3134     }
3135 #endif
3136 
3137     XMEMSET(bench_tag, 0, AES_AUTH_TAG_SZ);
3138     XMEMSET(bench_additional, 0, AES_AUTH_ADD_SZ);
3139 
3140     if ((ret = wc_AesCcmSetKey(&enc, bench_key, 16)) != 0) {
3141         printf("wc_AesCcmSetKey failed, ret = %d\n", ret);
3142         goto exit;
3143     }
3144 
3145     bench_stats_start(&count, &start);
3146     do {
3147         for (i = 0; i < numBlocks; i++) {
3148             wc_AesCcmEncrypt(&enc, bench_cipher, bench_plain, BENCH_SIZE,
3149                 bench_iv, 12, bench_tag, AES_AUTH_TAG_SZ,
3150                 bench_additional, aesAuthAddSz);
3151         }
3152         count += i;
3153     } while (bench_stats_sym_check(start));
3154     bench_stats_sym_finish("AES-CCM-Enc", 0, count, bench_size, start, ret);
3155 
3156     bench_stats_start(&count, &start);
3157     do {
3158         for (i = 0; i < numBlocks; i++) {
3159             wc_AesCcmDecrypt(&enc, bench_plain, bench_cipher, BENCH_SIZE,
3160                 bench_iv, 12, bench_tag, AES_AUTH_TAG_SZ,
3161                 bench_additional, aesAuthAddSz);
3162         }
3163         count += i;
3164     } while (bench_stats_sym_check(start));
3165     bench_stats_sym_finish("AES-CCM-Dec", 0, count, bench_size, start, ret);
3166 
3167   exit:
3168 
3169     WC_FREE_VAR(bench_additional, HEAP_HINT);
3170     WC_FREE_VAR(bench_tag, HEAP_HINT);
3171 }
3172 #endif /* HAVE_AESCCM */
3173 #endif /* !NO_AES */
3174 
3175 
3176 #ifdef HAVE_POLY1305
bench_poly1305(void)3177 void bench_poly1305(void)
3178 {
3179     Poly1305 enc;
3180     byte     mac[16];
3181     double   start;
3182     int      ret = 0, i, count;
3183 
3184     if (digest_stream) {
3185         ret = wc_Poly1305SetKey(&enc, bench_key, 32);
3186         if (ret != 0) {
3187             printf("Poly1305SetKey failed, ret = %d\n", ret);
3188             return;
3189         }
3190 
3191         bench_stats_start(&count, &start);
3192         do {
3193             for (i = 0; i < numBlocks; i++) {
3194                 ret = wc_Poly1305Update(&enc, bench_plain, BENCH_SIZE);
3195                 if (ret != 0) {
3196                     printf("Poly1305Update failed: %d\n", ret);
3197                     break;
3198                 }
3199             }
3200             wc_Poly1305Final(&enc, mac);
3201             count += i;
3202         } while (bench_stats_sym_check(start));
3203         bench_stats_sym_finish("POLY1305", 0, count, bench_size, start, ret);
3204     }
3205     else {
3206         bench_stats_start(&count, &start);
3207         do {
3208             for (i = 0; i < numBlocks; i++) {
3209                 ret = wc_Poly1305SetKey(&enc, bench_key, 32);
3210                 if (ret != 0) {
3211                     printf("Poly1305SetKey failed, ret = %d\n", ret);
3212                     return;
3213                 }
3214                 ret = wc_Poly1305Update(&enc, bench_plain, BENCH_SIZE);
3215                 if (ret != 0) {
3216                     printf("Poly1305Update failed: %d\n", ret);
3217                     break;
3218                 }
3219                 wc_Poly1305Final(&enc, mac);
3220             }
3221             count += i;
3222         } while (bench_stats_sym_check(start));
3223         bench_stats_sym_finish("POLY1305", 0, count, bench_size, start, ret);
3224     }
3225 }
3226 #endif /* HAVE_POLY1305 */
3227 
3228 
3229 #ifdef HAVE_CAMELLIA
bench_camellia(void)3230 void bench_camellia(void)
3231 {
3232     Camellia cam;
3233     double   start;
3234     int      ret, i, count;
3235 
3236     ret = wc_CamelliaSetKey(&cam, bench_key, 16, bench_iv);
3237     if (ret != 0) {
3238         printf("CamelliaSetKey failed, ret = %d\n", ret);
3239         return;
3240     }
3241 
3242     bench_stats_start(&count, &start);
3243     do {
3244         for (i = 0; i < numBlocks; i++) {
3245             ret = wc_CamelliaCbcEncrypt(&cam, bench_plain, bench_cipher,
3246                                                             BENCH_SIZE);
3247             if (ret < 0) {
3248                 printf("CamelliaCbcEncrypt failed: %d\n", ret);
3249                 return;
3250             }
3251         }
3252         count += i;
3253     } while (bench_stats_sym_check(start));
3254     bench_stats_sym_finish("Camellia", 0, count, bench_size, start, ret);
3255 }
3256 #endif
3257 
3258 
3259 #ifndef NO_DES3
bench_des(int doAsync)3260 void bench_des(int doAsync)
3261 {
3262     int    ret = 0, i, count = 0, times, pending = 0;
3263     Des3   enc[BENCH_MAX_PENDING];
3264     double start;
3265 
3266     /* clear for done cleanup */
3267     XMEMSET(enc, 0, sizeof(enc));
3268 
3269     /* init keys */
3270     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3271         if ((ret = wc_Des3Init(&enc[i], HEAP_HINT,
3272                                 doAsync ? devId : INVALID_DEVID)) != 0) {
3273             printf("Des3Init failed, ret = %d\n", ret);
3274             goto exit;
3275         }
3276 
3277         ret = wc_Des3_SetKey(&enc[i], bench_key, bench_iv, DES_ENCRYPTION);
3278         if (ret != 0) {
3279             printf("Des3_SetKey failed, ret = %d\n", ret);
3280             goto exit;
3281         }
3282     }
3283 
3284     bench_stats_start(&count, &start);
3285     do {
3286         for (times = 0; times < numBlocks || pending > 0; ) {
3287             bench_async_poll(&pending);
3288 
3289             /* while free pending slots in queue, submit ops */
3290             for (i = 0; i < BENCH_MAX_PENDING; i++) {
3291                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
3292                     ret = wc_Des3_CbcEncrypt(&enc[i], bench_plain, bench_cipher,
3293                         BENCH_SIZE);
3294                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
3295                         goto exit_3des;
3296                     }
3297                 }
3298             } /* for i */
3299         } /* for times */
3300         count += times;
3301     } while (bench_stats_sym_check(start));
3302 exit_3des:
3303     bench_stats_sym_finish("3DES", doAsync, count, bench_size, start, ret);
3304 
3305 exit:
3306 
3307     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3308         wc_Des3Free(&enc[i]);
3309     }
3310 }
3311 #endif /* !NO_DES3 */
3312 
3313 
3314 #ifdef HAVE_IDEA
bench_idea(void)3315 void bench_idea(void)
3316 {
3317     Idea   enc;
3318     double start;
3319     int    ret = 0, i, count;
3320 
3321     ret = wc_IdeaSetKey(&enc, bench_key, IDEA_KEY_SIZE, bench_iv,
3322         IDEA_ENCRYPTION);
3323     if (ret != 0) {
3324         printf("Des3_SetKey failed, ret = %d\n", ret);
3325         return;
3326     }
3327 
3328     bench_stats_start(&count, &start);
3329     do {
3330         for (i = 0; i < numBlocks; i++) {
3331             wc_IdeaCbcEncrypt(&enc, bench_plain, bench_cipher, BENCH_SIZE);
3332         }
3333         count += i;
3334     } while (bench_stats_sym_check(start));
3335     bench_stats_sym_finish("IDEA", 0, count, bench_size, start, ret);
3336 }
3337 #endif /* HAVE_IDEA */
3338 
3339 
3340 #ifndef NO_RC4
bench_arc4(int doAsync)3341 void bench_arc4(int doAsync)
3342 {
3343     int    ret = 0, i, count = 0, times, pending = 0;
3344     Arc4   enc[BENCH_MAX_PENDING];
3345     double start;
3346 
3347     /* clear for done cleanup */
3348     XMEMSET(enc, 0, sizeof(enc));
3349 
3350     /* init keys */
3351     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3352         if ((ret = wc_Arc4Init(&enc[i], HEAP_HINT,
3353                             doAsync ? devId : INVALID_DEVID)) != 0) {
3354             printf("Arc4Init failed, ret = %d\n", ret);
3355             goto exit;
3356         }
3357 
3358         ret = wc_Arc4SetKey(&enc[i], bench_key, 16);
3359         if (ret != 0) {
3360             printf("Arc4SetKey failed, ret = %d\n", ret);
3361             goto exit;
3362         }
3363     }
3364 
3365     bench_stats_start(&count, &start);
3366     do {
3367         for (times = 0; times < numBlocks || pending > 0; ) {
3368             bench_async_poll(&pending);
3369 
3370             /* while free pending slots in queue, submit ops */
3371             for (i = 0; i < BENCH_MAX_PENDING; i++) {
3372                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, numBlocks, &pending)) {
3373                     ret = wc_Arc4Process(&enc[i], bench_cipher, bench_plain,
3374                         BENCH_SIZE);
3375                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&enc[i]), 0, &times, &pending)) {
3376                         goto exit_arc4;
3377                     }
3378                 }
3379             } /* for i */
3380         } /* for times */
3381         count += times;
3382     } while (bench_stats_sym_check(start));
3383 exit_arc4:
3384     bench_stats_sym_finish("ARC4", doAsync, count, bench_size, start, ret);
3385 
3386 exit:
3387 
3388     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3389         wc_Arc4Free(&enc[i]);
3390     }
3391 }
3392 #endif /* !NO_RC4 */
3393 
3394 
3395 #ifdef HAVE_HC128
bench_hc128(void)3396 void bench_hc128(void)
3397 {
3398     HC128  enc;
3399     double start;
3400     int    i, count;
3401 
3402     wc_Hc128_SetKey(&enc, bench_key, bench_iv);
3403 
3404     bench_stats_start(&count, &start);
3405     do {
3406         for (i = 0; i < numBlocks; i++) {
3407             wc_Hc128_Process(&enc, bench_cipher, bench_plain, BENCH_SIZE);
3408         }
3409         count += i;
3410     } while (bench_stats_sym_check(start));
3411     bench_stats_sym_finish("HC128", 0, count, bench_size, start, 0);
3412 }
3413 #endif /* HAVE_HC128 */
3414 
3415 
3416 #ifndef NO_RABBIT
bench_rabbit(void)3417 void bench_rabbit(void)
3418 {
3419     Rabbit enc;
3420     double start;
3421     int    i, count;
3422 
3423     wc_RabbitSetKey(&enc, bench_key, bench_iv);
3424 
3425     bench_stats_start(&count, &start);
3426     do {
3427         for (i = 0; i < numBlocks; i++) {
3428             wc_RabbitProcess(&enc, bench_cipher, bench_plain, BENCH_SIZE);
3429         }
3430         count += i;
3431     } while (bench_stats_sym_check(start));
3432     bench_stats_sym_finish("RABBIT", 0, count, bench_size, start, 0);
3433 }
3434 #endif /* NO_RABBIT */
3435 
3436 
3437 #ifdef HAVE_CHACHA
bench_chacha(void)3438 void bench_chacha(void)
3439 {
3440     ChaCha enc;
3441     double start;
3442     int    i, count;
3443 
3444     wc_Chacha_SetKey(&enc, bench_key, 16);
3445 
3446     bench_stats_start(&count, &start);
3447     do {
3448         for (i = 0; i < numBlocks; i++) {
3449             wc_Chacha_SetIV(&enc, bench_iv, 0);
3450             wc_Chacha_Process(&enc, bench_cipher, bench_plain, BENCH_SIZE);
3451         }
3452         count += i;
3453     } while (bench_stats_sym_check(start));
3454     bench_stats_sym_finish("CHACHA", 0, count, bench_size, start, 0);
3455 }
3456 #endif /* HAVE_CHACHA*/
3457 
3458 #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
bench_chacha20_poly1305_aead(void)3459 void bench_chacha20_poly1305_aead(void)
3460 {
3461     double start;
3462     int    ret = 0, i, count;
3463 
3464     byte authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];
3465     XMEMSET(authTag, 0, sizeof(authTag));
3466 
3467     bench_stats_start(&count, &start);
3468     do {
3469         for (i = 0; i < numBlocks; i++) {
3470             ret = wc_ChaCha20Poly1305_Encrypt(bench_key, bench_iv, NULL, 0,
3471                 bench_plain, BENCH_SIZE, bench_cipher, authTag);
3472             if (ret < 0) {
3473                 printf("wc_ChaCha20Poly1305_Encrypt error: %d\n", ret);
3474                 break;
3475             }
3476         }
3477         count += i;
3478     } while (bench_stats_sym_check(start));
3479     bench_stats_sym_finish("CHA-POLY", 0, count, bench_size, start, ret);
3480 }
3481 #endif /* HAVE_CHACHA && HAVE_POLY1305 */
3482 
3483 
3484 #ifndef NO_MD5
bench_md5(int doAsync)3485 void bench_md5(int doAsync)
3486 {
3487     wc_Md5 hash[BENCH_MAX_PENDING];
3488     double start;
3489     int    ret = 0, i, count = 0, times, pending = 0;
3490     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_MD5_DIGEST_SIZE, HEAP_HINT);
3491 
3492     /* clear for done cleanup */
3493     XMEMSET(hash, 0, sizeof(hash));
3494 
3495     if (digest_stream) {
3496         /* init keys */
3497         for (i = 0; i < BENCH_MAX_PENDING; i++) {
3498             ret = wc_InitMd5_ex(&hash[i], HEAP_HINT,
3499                         doAsync ? devId : INVALID_DEVID);
3500             if (ret != 0) {
3501                 printf("InitMd5_ex failed, ret = %d\n", ret);
3502                 goto exit;
3503             }
3504         #ifdef WOLFSSL_PIC32MZ_HASH
3505             wc_Md5SizeSet(&hash[i], numBlocks * BENCH_SIZE);
3506         #endif
3507         }
3508 
3509         bench_stats_start(&count, &start);
3510         do {
3511             for (times = 0; times < numBlocks || pending > 0; ) {
3512                 bench_async_poll(&pending);
3513 
3514                 /* while free pending slots in queue, submit ops */
3515                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3516                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3517                         ret = wc_Md5Update(&hash[i], bench_plain,
3518                             BENCH_SIZE);
3519                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3520                             goto exit_md5;
3521                         }
3522                     }
3523                 } /* for i */
3524             } /* for times */
3525             count += times;
3526 
3527             times = 0;
3528             do {
3529                 bench_async_poll(&pending);
3530 
3531                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3532                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3533                         ret = wc_Md5Final(&hash[i], digest[i]);
3534                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3535                             goto exit_md5;
3536                         }
3537                     }
3538                 } /* for i */
3539             } while (pending > 0);
3540         } while (bench_stats_sym_check(start));
3541     }
3542     else {
3543         bench_stats_start(&count, &start);
3544         do {
3545             for (times = 0; times < numBlocks; times++) {
3546                 ret = wc_InitMd5_ex(hash, HEAP_HINT, INVALID_DEVID);
3547                 ret |= wc_Md5Update(hash, bench_plain, BENCH_SIZE);
3548                 ret |= wc_Md5Final(hash, digest[0]);
3549                 if (ret != 0)
3550                     goto exit_md5;
3551             } /* for times */
3552             count += times;
3553         } while (bench_stats_sym_check(start));
3554     }
3555 exit_md5:
3556     bench_stats_sym_finish("MD5", doAsync, count, bench_size, start, ret);
3557 
3558 exit:
3559 
3560 #ifdef WOLFSSL_ASYNC_CRYPT
3561     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3562         wc_Md5Free(&hash[i]);
3563     }
3564 #endif
3565 
3566     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
3567 }
3568 #endif /* !NO_MD5 */
3569 
3570 
3571 #ifndef NO_SHA
bench_sha(int doAsync)3572 void bench_sha(int doAsync)
3573 {
3574     wc_Sha hash[BENCH_MAX_PENDING];
3575     double start;
3576     int    ret = 0, i, count = 0, times, pending = 0;
3577     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA_DIGEST_SIZE, HEAP_HINT);
3578 
3579     /* clear for done cleanup */
3580     XMEMSET(hash, 0, sizeof(hash));
3581 
3582     if (digest_stream) {
3583         /* init keys */
3584         for (i = 0; i < BENCH_MAX_PENDING; i++) {
3585             ret = wc_InitSha_ex(&hash[i], HEAP_HINT,
3586                 doAsync ? devId : INVALID_DEVID);
3587             if (ret != 0) {
3588                 printf("InitSha failed, ret = %d\n", ret);
3589                 goto exit;
3590             }
3591         #ifdef WOLFSSL_PIC32MZ_HASH
3592             wc_ShaSizeSet(&hash[i], numBlocks * BENCH_SIZE);
3593         #endif
3594         }
3595 
3596         bench_stats_start(&count, &start);
3597         do {
3598             for (times = 0; times < numBlocks || pending > 0; ) {
3599                 bench_async_poll(&pending);
3600 
3601                 /* while free pending slots in queue, submit ops */
3602                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3603                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3604                         ret = wc_ShaUpdate(&hash[i], bench_plain,
3605                             BENCH_SIZE);
3606                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3607                             goto exit_sha;
3608                         }
3609                     }
3610                 } /* for i */
3611             } /* for times */
3612             count += times;
3613 
3614             times = 0;
3615             do {
3616                 bench_async_poll(&pending);
3617 
3618                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3619                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3620                         ret = wc_ShaFinal(&hash[i], digest[i]);
3621                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3622                             goto exit_sha;
3623                         }
3624                     }
3625                 } /* for i */
3626             } while (pending > 0);
3627         } while (bench_stats_sym_check(start));
3628     }
3629     else {
3630         bench_stats_start(&count, &start);
3631         do {
3632             for (times = 0; times < numBlocks; times++) {
3633                 ret = wc_InitSha_ex(hash, HEAP_HINT, INVALID_DEVID);
3634                 ret |= wc_ShaUpdate(hash, bench_plain, BENCH_SIZE);
3635                 ret |= wc_ShaFinal(hash, digest[0]);
3636                 if (ret != 0)
3637                     goto exit_sha;
3638             } /* for times */
3639             count += times;
3640         } while (bench_stats_sym_check(start));
3641     }
3642 exit_sha:
3643     bench_stats_sym_finish("SHA", doAsync, count, bench_size, start, ret);
3644 
3645 exit:
3646 
3647     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3648         wc_ShaFree(&hash[i]);
3649     }
3650 
3651     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
3652 }
3653 #endif /* NO_SHA */
3654 
3655 
3656 #ifdef WOLFSSL_SHA224
bench_sha224(int doAsync)3657 void bench_sha224(int doAsync)
3658 {
3659     wc_Sha224 hash[BENCH_MAX_PENDING];
3660     double start;
3661     int    ret = 0, i, count = 0, times, pending = 0;
3662     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA224_DIGEST_SIZE, HEAP_HINT);
3663 
3664     /* clear for done cleanup */
3665     XMEMSET(hash, 0, sizeof(hash));
3666 
3667     if (digest_stream) {
3668         /* init keys */
3669         for (i = 0; i < BENCH_MAX_PENDING; i++) {
3670             ret = wc_InitSha224_ex(&hash[i], HEAP_HINT,
3671                 doAsync ? devId : INVALID_DEVID);
3672             if (ret != 0) {
3673                 printf("InitSha224_ex failed, ret = %d\n", ret);
3674                 goto exit;
3675             }
3676         }
3677 
3678         bench_stats_start(&count, &start);
3679         do {
3680             for (times = 0; times < numBlocks || pending > 0; ) {
3681                 bench_async_poll(&pending);
3682 
3683                 /* while free pending slots in queue, submit ops */
3684                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3685                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3686                         ret = wc_Sha224Update(&hash[i], bench_plain,
3687                             BENCH_SIZE);
3688                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3689                             goto exit_sha224;
3690                         }
3691                     }
3692                 } /* for i */
3693             } /* for times */
3694             count += times;
3695 
3696             times = 0;
3697             do {
3698                 bench_async_poll(&pending);
3699                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3700                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3701                         ret = wc_Sha224Final(&hash[i], digest[i]);
3702                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3703                             goto exit_sha224;
3704                         }
3705                     }
3706                 } /* for i */
3707             } while (pending > 0);
3708         } while (bench_stats_sym_check(start));
3709     }
3710     else {
3711         bench_stats_start(&count, &start);
3712         do {
3713             for (times = 0; times < numBlocks; times++) {
3714                 ret = wc_InitSha224_ex(hash, HEAP_HINT, INVALID_DEVID);
3715                 ret |= wc_Sha224Update(hash, bench_plain, BENCH_SIZE);
3716                 ret |= wc_Sha224Final(hash, digest[0]);
3717                 if (ret != 0)
3718                     goto exit_sha224;
3719             } /* for times */
3720             count += times;
3721         } while (bench_stats_sym_check(start));
3722     }
3723 exit_sha224:
3724     bench_stats_sym_finish("SHA-224", doAsync, count, bench_size, start, ret);
3725 
3726 exit:
3727 
3728     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3729         wc_Sha224Free(&hash[i]);
3730     }
3731 
3732     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
3733 }
3734 #endif
3735 
3736 #ifndef NO_SHA256
bench_sha256(int doAsync)3737 void bench_sha256(int doAsync)
3738 {
3739     wc_Sha256 hash[BENCH_MAX_PENDING];
3740     double start;
3741     int    ret = 0, i, count = 0, times, pending = 0;
3742     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA256_DIGEST_SIZE, HEAP_HINT);
3743 
3744     /* clear for done cleanup */
3745     XMEMSET(hash, 0, sizeof(hash));
3746 
3747     if (digest_stream) {
3748         /* init keys */
3749         for (i = 0; i < BENCH_MAX_PENDING; i++) {
3750             ret = wc_InitSha256_ex(&hash[i], HEAP_HINT,
3751                 doAsync ? devId : INVALID_DEVID);
3752             if (ret != 0) {
3753                 printf("InitSha256_ex failed, ret = %d\n", ret);
3754                 goto exit;
3755             }
3756         #ifdef WOLFSSL_PIC32MZ_HASH
3757             wc_Sha256SizeSet(&hash[i], numBlocks * BENCH_SIZE);
3758         #endif
3759         }
3760 
3761         bench_stats_start(&count, &start);
3762         do {
3763             for (times = 0; times < numBlocks || pending > 0; ) {
3764                 bench_async_poll(&pending);
3765 
3766                 /* while free pending slots in queue, submit ops */
3767                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3768                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3769                         ret = wc_Sha256Update(&hash[i], bench_plain,
3770                             BENCH_SIZE);
3771                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3772                             goto exit_sha256;
3773                         }
3774                     }
3775                 } /* for i */
3776             } /* for times */
3777             count += times;
3778 
3779             times = 0;
3780             do {
3781                 bench_async_poll(&pending);
3782                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3783                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3784                         ret = wc_Sha256Final(&hash[i], digest[i]);
3785                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3786                             goto exit_sha256;
3787                         }
3788                     }
3789                 } /* for i */
3790             } while (pending > 0);
3791         } while (bench_stats_sym_check(start));
3792     }
3793     else {
3794         bench_stats_start(&count, &start);
3795         do {
3796             for (times = 0; times < numBlocks; times++) {
3797                 ret = wc_InitSha256_ex(hash, HEAP_HINT, INVALID_DEVID);
3798                 ret |= wc_Sha256Update(hash, bench_plain, BENCH_SIZE);
3799                 ret |= wc_Sha256Final(hash, digest[0]);
3800                 if (ret != 0)
3801                     goto exit_sha256;
3802             } /* for times */
3803             count += times;
3804         } while (bench_stats_sym_check(start));
3805     }
3806 exit_sha256:
3807     bench_stats_sym_finish("SHA-256", doAsync, count, bench_size, start, ret);
3808 
3809 exit:
3810 
3811     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3812         wc_Sha256Free(&hash[i]);
3813     }
3814 
3815     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
3816 }
3817 #endif
3818 
3819 #ifdef WOLFSSL_SHA384
bench_sha384(int doAsync)3820 void bench_sha384(int doAsync)
3821 {
3822     wc_Sha384 hash[BENCH_MAX_PENDING];
3823     double start;
3824     int    ret = 0, i, count = 0, times, pending = 0;
3825     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA384_DIGEST_SIZE, HEAP_HINT);
3826 
3827     /* clear for done cleanup */
3828     XMEMSET(hash, 0, sizeof(hash));
3829 
3830     if (digest_stream) {
3831         /* init keys */
3832         for (i = 0; i < BENCH_MAX_PENDING; i++) {
3833             ret = wc_InitSha384_ex(&hash[i], HEAP_HINT,
3834                 doAsync ? devId : INVALID_DEVID);
3835             if (ret != 0) {
3836                 printf("InitSha384_ex failed, ret = %d\n", ret);
3837                 goto exit;
3838             }
3839         }
3840 
3841         bench_stats_start(&count, &start);
3842         do {
3843             for (times = 0; times < numBlocks || pending > 0; ) {
3844                 bench_async_poll(&pending);
3845 
3846                 /* while free pending slots in queue, submit ops */
3847                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3848                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3849                         ret = wc_Sha384Update(&hash[i], bench_plain,
3850                             BENCH_SIZE);
3851                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3852                             goto exit_sha384;
3853                         }
3854                     }
3855                 } /* for i */
3856             } /* for times */
3857             count += times;
3858 
3859             times = 0;
3860             do {
3861                 bench_async_poll(&pending);
3862                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3863                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3864                         ret = wc_Sha384Final(&hash[i], digest[i]);
3865                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3866                             goto exit_sha384;
3867                         }
3868                     }
3869                 } /* for i */
3870             } while (pending > 0);
3871         } while (bench_stats_sym_check(start));
3872     }
3873     else {
3874         bench_stats_start(&count, &start);
3875         do {
3876             for (times = 0; times < numBlocks; times++) {
3877                 ret = wc_InitSha384_ex(hash, HEAP_HINT, INVALID_DEVID);
3878                 ret |= wc_Sha384Update(hash, bench_plain, BENCH_SIZE);
3879                 ret |= wc_Sha384Final(hash, digest[0]);
3880                 if (ret != 0)
3881                     goto exit_sha384;
3882             } /* for times */
3883             count += times;
3884         } while (bench_stats_sym_check(start));
3885     }
3886 exit_sha384:
3887     bench_stats_sym_finish("SHA-384", doAsync, count, bench_size, start, ret);
3888 
3889 exit:
3890 
3891     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3892         wc_Sha384Free(&hash[i]);
3893     }
3894 
3895     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
3896 }
3897 #endif
3898 
3899 #ifdef WOLFSSL_SHA512
bench_sha512(int doAsync)3900 void bench_sha512(int doAsync)
3901 {
3902     wc_Sha512 hash[BENCH_MAX_PENDING];
3903     double start;
3904     int    ret = 0, i, count = 0, times, pending = 0;
3905     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA512_DIGEST_SIZE, HEAP_HINT);
3906 
3907     /* clear for done cleanup */
3908     XMEMSET(hash, 0, sizeof(hash));
3909 
3910     if (digest_stream) {
3911         /* init keys */
3912         for (i = 0; i < BENCH_MAX_PENDING; i++) {
3913             ret = wc_InitSha512_ex(&hash[i], HEAP_HINT,
3914                 doAsync ? devId : INVALID_DEVID);
3915             if (ret != 0) {
3916                 printf("InitSha512_ex failed, ret = %d\n", ret);
3917                 goto exit;
3918             }
3919         }
3920 
3921         bench_stats_start(&count, &start);
3922         do {
3923             for (times = 0; times < numBlocks || pending > 0; ) {
3924                 bench_async_poll(&pending);
3925 
3926                 /* while free pending slots in queue, submit ops */
3927                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3928                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3929                         ret = wc_Sha512Update(&hash[i], bench_plain,
3930                             BENCH_SIZE);
3931                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3932                             goto exit_sha512;
3933                         }
3934                     }
3935                 } /* for i */
3936             } /* for times */
3937             count += times;
3938 
3939             times = 0;
3940             do {
3941                 bench_async_poll(&pending);
3942                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
3943                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
3944                         ret = wc_Sha512Final(&hash[i], digest[i]);
3945                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
3946                             goto exit_sha512;
3947                         }
3948                     }
3949                 } /* for i */
3950             } while (pending > 0);
3951         } while (bench_stats_sym_check(start));
3952     }
3953     else {
3954         bench_stats_start(&count, &start);
3955         do {
3956             for (times = 0; times < numBlocks; times++) {
3957                 ret = wc_InitSha512_ex(hash, HEAP_HINT, INVALID_DEVID);
3958                 ret |= wc_Sha512Update(hash, bench_plain, BENCH_SIZE);
3959                 ret |= wc_Sha512Final(hash, digest[0]);
3960                 if (ret != 0)
3961                     goto exit_sha512;
3962             } /* for times */
3963             count += times;
3964         } while (bench_stats_sym_check(start));
3965     }
3966 exit_sha512:
3967     bench_stats_sym_finish("SHA-512", doAsync, count, bench_size, start, ret);
3968 
3969 exit:
3970 
3971     for (i = 0; i < BENCH_MAX_PENDING; i++) {
3972         wc_Sha512Free(&hash[i]);
3973     }
3974 
3975     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
3976 }
3977 #endif
3978 
3979 
3980 #ifdef WOLFSSL_SHA3
3981 #ifndef WOLFSSL_NOSHA3_224
bench_sha3_224(int doAsync)3982 void bench_sha3_224(int doAsync)
3983 {
3984     wc_Sha3   hash[BENCH_MAX_PENDING];
3985     double start;
3986     int    ret = 0, i, count = 0, times, pending = 0;
3987     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA3_224_DIGEST_SIZE, HEAP_HINT);
3988 
3989     /* clear for done cleanup */
3990     XMEMSET(hash, 0, sizeof(hash));
3991 
3992     if (digest_stream) {
3993         /* init keys */
3994         for (i = 0; i < BENCH_MAX_PENDING; i++) {
3995             ret = wc_InitSha3_224(&hash[i], HEAP_HINT,
3996                 doAsync ? devId : INVALID_DEVID);
3997             if (ret != 0) {
3998                 printf("InitSha3_224 failed, ret = %d\n", ret);
3999                 goto exit;
4000             }
4001         }
4002 
4003         bench_stats_start(&count, &start);
4004         do {
4005             for (times = 0; times < numBlocks || pending > 0; ) {
4006                 bench_async_poll(&pending);
4007 
4008                 /* while free pending slots in queue, submit ops */
4009                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4010                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4011                         ret = wc_Sha3_224_Update(&hash[i], bench_plain,
4012                             BENCH_SIZE);
4013                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4014                             goto exit_sha3_224;
4015                         }
4016                     }
4017                 } /* for i */
4018             } /* for times */
4019             count += times;
4020 
4021             times = 0;
4022             do {
4023                 bench_async_poll(&pending);
4024                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4025                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4026                         ret = wc_Sha3_224_Final(&hash[i], digest[i]);
4027                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4028                             goto exit_sha3_224;
4029                         }
4030                     }
4031                 } /* for i */
4032             } while (pending > 0);
4033         } while (bench_stats_sym_check(start));
4034     }
4035     else {
4036         bench_stats_start(&count, &start);
4037         do {
4038             for (times = 0; times < numBlocks; times++) {
4039                 ret = wc_InitSha3_224(hash, HEAP_HINT, INVALID_DEVID);
4040                 ret |= wc_Sha3_224_Update(hash, bench_plain, BENCH_SIZE);
4041                 ret |= wc_Sha3_224_Final(hash, digest[0]);
4042                 if (ret != 0)
4043                     goto exit_sha3_224;
4044             } /* for times */
4045             count += times;
4046         } while (bench_stats_sym_check(start));
4047     }
4048 exit_sha3_224:
4049     bench_stats_sym_finish("SHA3-224", doAsync, count, bench_size, start, ret);
4050 
4051 exit:
4052 
4053     for (i = 0; i < BENCH_MAX_PENDING; i++) {
4054         wc_Sha3_224_Free(&hash[i]);
4055     }
4056 
4057     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
4058 }
4059 #endif /* WOLFSSL_NOSHA3_224 */
4060 
4061 #ifndef WOLFSSL_NOSHA3_256
bench_sha3_256(int doAsync)4062 void bench_sha3_256(int doAsync)
4063 {
4064     wc_Sha3   hash[BENCH_MAX_PENDING];
4065     double start;
4066     int    ret = 0, i, count = 0, times, pending = 0;
4067     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA3_256_DIGEST_SIZE, HEAP_HINT);
4068 
4069     /* clear for done cleanup */
4070     XMEMSET(hash, 0, sizeof(hash));
4071 
4072     if (digest_stream) {
4073         /* init keys */
4074         for (i = 0; i < BENCH_MAX_PENDING; i++) {
4075             ret = wc_InitSha3_256(&hash[i], HEAP_HINT,
4076                 doAsync ? devId : INVALID_DEVID);
4077             if (ret != 0) {
4078                 printf("InitSha3_256 failed, ret = %d\n", ret);
4079                 goto exit;
4080             }
4081         }
4082 
4083         bench_stats_start(&count, &start);
4084         do {
4085             for (times = 0; times < numBlocks || pending > 0; ) {
4086                 bench_async_poll(&pending);
4087 
4088                 /* while free pending slots in queue, submit ops */
4089                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4090                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4091                         ret = wc_Sha3_256_Update(&hash[i], bench_plain,
4092                             BENCH_SIZE);
4093                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4094                             goto exit_sha3_256;
4095                         }
4096                     }
4097                 } /* for i */
4098             } /* for times */
4099             count += times;
4100 
4101             times = 0;
4102             do {
4103                 bench_async_poll(&pending);
4104                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4105                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4106                         ret = wc_Sha3_256_Final(&hash[i], digest[i]);
4107                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4108                             goto exit_sha3_256;
4109                         }
4110                     }
4111                 } /* for i */
4112             } while (pending > 0);
4113         } while (bench_stats_sym_check(start));
4114     }
4115     else {
4116         bench_stats_start(&count, &start);
4117         do {
4118             for (times = 0; times < numBlocks; times++) {
4119                 ret = wc_InitSha3_256(hash, HEAP_HINT, INVALID_DEVID);
4120                 ret |= wc_Sha3_256_Update(hash, bench_plain, BENCH_SIZE);
4121                 ret |= wc_Sha3_256_Final(hash, digest[0]);
4122                 if (ret != 0)
4123                     goto exit_sha3_256;
4124             } /* for times */
4125             count += times;
4126         } while (bench_stats_sym_check(start));
4127     }
4128 exit_sha3_256:
4129     bench_stats_sym_finish("SHA3-256", doAsync, count, bench_size, start, ret);
4130 
4131 exit:
4132 
4133     for (i = 0; i < BENCH_MAX_PENDING; i++) {
4134         wc_Sha3_256_Free(&hash[i]);
4135     }
4136 
4137     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
4138 }
4139 #endif /* WOLFSSL_NOSHA3_256 */
4140 
4141 #ifndef WOLFSSL_NOSHA3_384
bench_sha3_384(int doAsync)4142 void bench_sha3_384(int doAsync)
4143 {
4144     wc_Sha3   hash[BENCH_MAX_PENDING];
4145     double start;
4146     int    ret = 0, i, count = 0, times, pending = 0;
4147     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA3_384_DIGEST_SIZE, HEAP_HINT);
4148 
4149     /* clear for done cleanup */
4150     XMEMSET(hash, 0, sizeof(hash));
4151 
4152     if (digest_stream) {
4153         /* init keys */
4154         for (i = 0; i < BENCH_MAX_PENDING; i++) {
4155             ret = wc_InitSha3_384(&hash[i], HEAP_HINT,
4156                 doAsync ? devId : INVALID_DEVID);
4157             if (ret != 0) {
4158                 printf("InitSha3_384 failed, ret = %d\n", ret);
4159                 goto exit;
4160             }
4161         }
4162 
4163         bench_stats_start(&count, &start);
4164         do {
4165             for (times = 0; times < numBlocks || pending > 0; ) {
4166                 bench_async_poll(&pending);
4167 
4168                 /* while free pending slots in queue, submit ops */
4169                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4170                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4171                         ret = wc_Sha3_384_Update(&hash[i], bench_plain,
4172                             BENCH_SIZE);
4173                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4174                             goto exit_sha3_384;
4175                         }
4176                     }
4177                 } /* for i */
4178             } /* for times */
4179             count += times;
4180 
4181             times = 0;
4182             do {
4183                 bench_async_poll(&pending);
4184                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4185                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4186                         ret = wc_Sha3_384_Final(&hash[i], digest[i]);
4187                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4188                             goto exit_sha3_384;
4189                         }
4190                     }
4191                 } /* for i */
4192             } while (pending > 0);
4193         } while (bench_stats_sym_check(start));
4194     }
4195     else {
4196         bench_stats_start(&count, &start);
4197         do {
4198             for (times = 0; times < numBlocks; times++) {
4199                 ret = wc_InitSha3_384(hash, HEAP_HINT, INVALID_DEVID);
4200                 ret |= wc_Sha3_384_Update(hash, bench_plain, BENCH_SIZE);
4201                 ret |= wc_Sha3_384_Final(hash, digest[0]);
4202                 if (ret != 0)
4203                     goto exit_sha3_384;
4204             } /* for times */
4205             count += times;
4206         } while (bench_stats_sym_check(start));
4207     }
4208 exit_sha3_384:
4209     bench_stats_sym_finish("SHA3-384", doAsync, count, bench_size, start, ret);
4210 
4211 exit:
4212 
4213     for (i = 0; i < BENCH_MAX_PENDING; i++) {
4214         wc_Sha3_384_Free(&hash[i]);
4215     }
4216 
4217     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
4218 }
4219 #endif /* WOLFSSL_NOSHA3_384 */
4220 
4221 #ifndef WOLFSSL_NOSHA3_512
bench_sha3_512(int doAsync)4222 void bench_sha3_512(int doAsync)
4223 {
4224     wc_Sha3   hash[BENCH_MAX_PENDING];
4225     double start;
4226     int    ret = 0, i, count = 0, times, pending = 0;
4227     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_SHA3_512_DIGEST_SIZE, HEAP_HINT);
4228 
4229     /* clear for done cleanup */
4230     XMEMSET(hash, 0, sizeof(hash));
4231 
4232     if (digest_stream) {
4233         /* init keys */
4234         for (i = 0; i < BENCH_MAX_PENDING; i++) {
4235             ret = wc_InitSha3_512(&hash[i], HEAP_HINT,
4236                 doAsync ? devId : INVALID_DEVID);
4237             if (ret != 0) {
4238                 printf("InitSha3_512 failed, ret = %d\n", ret);
4239                 goto exit;
4240             }
4241         }
4242 
4243         bench_stats_start(&count, &start);
4244         do {
4245             for (times = 0; times < numBlocks || pending > 0; ) {
4246                 bench_async_poll(&pending);
4247 
4248                 /* while free pending slots in queue, submit ops */
4249                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4250                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4251                         ret = wc_Sha3_512_Update(&hash[i], bench_plain,
4252                             BENCH_SIZE);
4253                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4254                             goto exit_sha3_512;
4255                         }
4256                     }
4257                 } /* for i */
4258             } /* for times */
4259             count += times;
4260 
4261             times = 0;
4262             do {
4263                 bench_async_poll(&pending);
4264                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4265                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, numBlocks, &pending)) {
4266                         ret = wc_Sha3_512_Final(&hash[i], digest[i]);
4267                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hash[i]), 0, &times, &pending)) {
4268                             goto exit_sha3_512;
4269                         }
4270                     }
4271                 } /* for i */
4272             } while (pending > 0);
4273         } while (bench_stats_sym_check(start));
4274     }
4275     else {
4276         bench_stats_start(&count, &start);
4277         do {
4278             for (times = 0; times < numBlocks; times++) {
4279                 ret = wc_InitSha3_512(hash, HEAP_HINT, INVALID_DEVID);
4280                 ret |= wc_Sha3_512_Update(hash, bench_plain, BENCH_SIZE);
4281                 ret |= wc_Sha3_512_Final(hash, digest[0]);
4282                 if (ret != 0)
4283                     goto exit_sha3_512;
4284             } /* for times */
4285             count += times;
4286         } while (bench_stats_sym_check(start));
4287     }
4288 exit_sha3_512:
4289     bench_stats_sym_finish("SHA3-512", doAsync, count, bench_size, start, ret);
4290 
4291 exit:
4292 
4293     for (i = 0; i < BENCH_MAX_PENDING; i++) {
4294         wc_Sha3_512_Free(&hash[i]);
4295     }
4296 
4297     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
4298 }
4299 #endif /* WOLFSSL_NOSHA3_512 */
4300 #endif
4301 
4302 
4303 #ifdef WOLFSSL_RIPEMD
bench_ripemd(void)4304 int bench_ripemd(void)
4305 {
4306     RipeMd hash;
4307     byte   digest[RIPEMD_DIGEST_SIZE];
4308     double start;
4309     int    i, count, ret = 0;
4310 
4311     if (digest_stream) {
4312         ret = wc_InitRipeMd(&hash);
4313         if (ret != 0) {
4314             return ret;
4315         }
4316 
4317         bench_stats_start(&count, &start);
4318         do {
4319             for (i = 0; i < numBlocks; i++) {
4320                 ret = wc_RipeMdUpdate(&hash, bench_plain, BENCH_SIZE);
4321                 if (ret != 0) {
4322                     return ret;
4323                 }
4324             }
4325             ret = wc_RipeMdFinal(&hash, digest);
4326             if (ret != 0) {
4327                 return ret;
4328             }
4329 
4330             count += i;
4331         } while (bench_stats_sym_check(start));
4332     }
4333     else {
4334         bench_stats_start(&count, &start);
4335         do {
4336             for (i = 0; i < numBlocks; i++) {
4337                 ret = wc_InitRipeMd(&hash);
4338                 if (ret != 0) {
4339                     return ret;
4340                 }
4341                 ret = wc_RipeMdUpdate(&hash, bench_plain, BENCH_SIZE);
4342                 if (ret != 0) {
4343                     return ret;
4344                 }
4345                 ret = wc_RipeMdFinal(&hash, digest);
4346                 if (ret != 0) {
4347                     return ret;
4348                 }
4349             }
4350             count += i;
4351         } while (bench_stats_sym_check(start));
4352     }
4353     bench_stats_sym_finish("RIPEMD", 0, count, bench_size, start, ret);
4354 
4355     return 0;
4356 }
4357 #endif
4358 
4359 
4360 #ifdef HAVE_BLAKE2
bench_blake2b(void)4361 void bench_blake2b(void)
4362 {
4363     Blake2b b2b;
4364     byte    digest[64];
4365     double  start;
4366     int     ret = 0, i, count;
4367 
4368     if (digest_stream) {
4369         ret = wc_InitBlake2b(&b2b, 64);
4370         if (ret != 0) {
4371             printf("InitBlake2b failed, ret = %d\n", ret);
4372             return;
4373         }
4374 
4375         bench_stats_start(&count, &start);
4376         do {
4377             for (i = 0; i < numBlocks; i++) {
4378                 ret = wc_Blake2bUpdate(&b2b, bench_plain, BENCH_SIZE);
4379                 if (ret != 0) {
4380                     printf("Blake2bUpdate failed, ret = %d\n", ret);
4381                     return;
4382                 }
4383             }
4384             ret = wc_Blake2bFinal(&b2b, digest, 64);
4385             if (ret != 0) {
4386                 printf("Blake2bFinal failed, ret = %d\n", ret);
4387                 return;
4388             }
4389             count += i;
4390         } while (bench_stats_sym_check(start));
4391     }
4392     else {
4393         bench_stats_start(&count, &start);
4394         do {
4395             for (i = 0; i < numBlocks; i++) {
4396                 ret = wc_InitBlake2b(&b2b, 64);
4397                 if (ret != 0) {
4398                     printf("InitBlake2b failed, ret = %d\n", ret);
4399                     return;
4400                 }
4401                 ret = wc_Blake2bUpdate(&b2b, bench_plain, BENCH_SIZE);
4402                 if (ret != 0) {
4403                     printf("Blake2bUpdate failed, ret = %d\n", ret);
4404                     return;
4405                 }
4406                 ret = wc_Blake2bFinal(&b2b, digest, 64);
4407                 if (ret != 0) {
4408                     printf("Blake2bFinal failed, ret = %d\n", ret);
4409                     return;
4410                 }
4411             }
4412             count += i;
4413         } while (bench_stats_sym_check(start));
4414     }
4415     bench_stats_sym_finish("BLAKE2b", 0, count, bench_size, start, ret);
4416 }
4417 #endif
4418 
4419 #if defined(HAVE_BLAKE2S)
bench_blake2s(void)4420 void bench_blake2s(void)
4421 {
4422     Blake2s b2s;
4423     byte    digest[32];
4424     double  start;
4425     int     ret = 0, i, count;
4426 
4427     if (digest_stream) {
4428         ret = wc_InitBlake2s(&b2s, 32);
4429         if (ret != 0) {
4430             printf("InitBlake2s failed, ret = %d\n", ret);
4431             return;
4432         }
4433 
4434         bench_stats_start(&count, &start);
4435         do {
4436             for (i = 0; i < numBlocks; i++) {
4437                 ret = wc_Blake2sUpdate(&b2s, bench_plain, BENCH_SIZE);
4438                 if (ret != 0) {
4439                     printf("Blake2sUpdate failed, ret = %d\n", ret);
4440                     return;
4441                 }
4442             }
4443             ret = wc_Blake2sFinal(&b2s, digest, 32);
4444             if (ret != 0) {
4445                 printf("Blake2sFinal failed, ret = %d\n", ret);
4446                 return;
4447             }
4448             count += i;
4449         } while (bench_stats_sym_check(start));
4450     }
4451     else {
4452         bench_stats_start(&count, &start);
4453         do {
4454             for (i = 0; i < numBlocks; i++) {
4455                 ret = wc_InitBlake2s(&b2s, 32);
4456                 if (ret != 0) {
4457                     printf("InitBlake2b failed, ret = %d\n", ret);
4458                     return;
4459                 }
4460                 ret = wc_Blake2sUpdate(&b2s, bench_plain, BENCH_SIZE);
4461                 if (ret != 0) {
4462                     printf("Blake2bUpdate failed, ret = %d\n", ret);
4463                     return;
4464                 }
4465                 ret = wc_Blake2sFinal(&b2s, digest, 32);
4466                 if (ret != 0) {
4467                     printf("Blake2sFinal failed, ret = %d\n", ret);
4468                     return;
4469                 }
4470             }
4471             count += i;
4472         } while (bench_stats_sym_check(start));
4473     }
4474     bench_stats_sym_finish("BLAKE2s", 0, count, bench_size, start, ret);
4475 }
4476 #endif
4477 
4478 
4479 #ifdef WOLFSSL_CMAC
4480 
bench_cmac_helper(int keySz,const char * outMsg)4481 static void bench_cmac_helper(int keySz, const char* outMsg)
4482 {
4483     Cmac    cmac;
4484     byte    digest[AES_BLOCK_SIZE];
4485     word32  digestSz = sizeof(digest);
4486     double  start;
4487     int     ret, i, count;
4488 
4489     bench_stats_start(&count, &start);
4490     do {
4491         ret = wc_InitCmac(&cmac, bench_key, keySz, WC_CMAC_AES, NULL);
4492         if (ret != 0) {
4493             printf("InitCmac failed, ret = %d\n", ret);
4494             return;
4495         }
4496 
4497         for (i = 0; i < numBlocks; i++) {
4498             ret = wc_CmacUpdate(&cmac, bench_plain, BENCH_SIZE);
4499             if (ret != 0) {
4500                 printf("CmacUpdate failed, ret = %d\n", ret);
4501                 return;
4502             }
4503         }
4504         /* Note: final force zero's the Cmac struct */
4505         ret = wc_CmacFinal(&cmac, digest, &digestSz);
4506         if (ret != 0) {
4507             printf("CmacFinal failed, ret = %d\n", ret);
4508             return;
4509         }
4510         count += i;
4511     } while (bench_stats_sym_check(start));
4512     bench_stats_sym_finish(outMsg, 0, count, bench_size, start, ret);
4513 }
4514 
bench_cmac(void)4515 void bench_cmac(void)
4516 {
4517 #ifdef WOLFSSL_AES_128
4518     bench_cmac_helper(16, "AES-128-CMAC");
4519 #endif
4520 #ifdef WOLFSSL_AES_256
4521     bench_cmac_helper(32, "AES-256-CMAC");
4522 #endif
4523 
4524 }
4525 #endif /* WOLFSSL_CMAC */
4526 
4527 #ifdef HAVE_SCRYPT
4528 
bench_scrypt(void)4529 void bench_scrypt(void)
4530 {
4531     byte   derived[64];
4532     double start;
4533     int    ret, i, count;
4534 
4535     bench_stats_start(&count, &start);
4536     do {
4537         for (i = 0; i < scryptCnt; i++) {
4538             ret = wc_scrypt(derived, (byte*)"pleaseletmein", 13,
4539                             (byte*)"SodiumChloride", 14, 14, 8, 1, sizeof(derived));
4540             if (ret != 0) {
4541                 printf("scrypt failed, ret = %d\n", ret);
4542                 goto exit;
4543             }
4544         }
4545         count += i;
4546     } while (bench_stats_sym_check(start));
4547 exit:
4548     bench_stats_asym_finish("scrypt", 17, "", 0, count, start, ret);
4549 }
4550 
4551 #endif /* HAVE_SCRYPT */
4552 
4553 #ifndef NO_HMAC
4554 
bench_hmac(int doAsync,int type,int digestSz,byte * key,word32 keySz,const char * label)4555 static void bench_hmac(int doAsync, int type, int digestSz,
4556                        byte* key, word32 keySz, const char* label)
4557 {
4558     Hmac   hmac[BENCH_MAX_PENDING];
4559     double start;
4560     int    ret = 0, i, count = 0, times, pending = 0;
4561 #ifdef WOLFSSL_ASYNC_CRYPT
4562     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, WC_MAX_DIGEST_SIZE, HEAP_HINT);
4563 #else
4564     byte digest[BENCH_MAX_PENDING][WC_MAX_DIGEST_SIZE];
4565 #endif
4566 
4567     (void)digestSz;
4568 
4569     /* clear for done cleanup */
4570     XMEMSET(hmac, 0, sizeof(hmac));
4571 
4572     /* init keys */
4573     for (i = 0; i < BENCH_MAX_PENDING; i++) {
4574         ret = wc_HmacInit(&hmac[i], HEAP_HINT,
4575                 doAsync ? devId : INVALID_DEVID);
4576         if (ret != 0) {
4577             printf("wc_HmacInit failed for %s, ret = %d\n", label, ret);
4578             goto exit;
4579         }
4580 
4581         ret = wc_HmacSetKey(&hmac[i], type, key, keySz);
4582         if (ret != 0) {
4583             printf("wc_HmacSetKey failed for %s, ret = %d\n", label, ret);
4584             goto exit;
4585         }
4586     }
4587 
4588     bench_stats_start(&count, &start);
4589     do {
4590         for (times = 0; times < numBlocks || pending > 0; ) {
4591             bench_async_poll(&pending);
4592 
4593             /* while free pending slots in queue, submit ops */
4594             for (i = 0; i < BENCH_MAX_PENDING; i++) {
4595                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hmac[i]), 0,
4596                                       &times, numBlocks, &pending)) {
4597                     ret = wc_HmacUpdate(&hmac[i], bench_plain, BENCH_SIZE);
4598                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hmac[i]),
4599                                             0, &times, &pending)) {
4600                         goto exit_hmac;
4601                     }
4602                 }
4603             } /* for i */
4604         } /* for times */
4605         count += times;
4606 
4607         times = 0;
4608         do {
4609             bench_async_poll(&pending);
4610 
4611             for (i = 0; i < BENCH_MAX_PENDING; i++) {
4612                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&hmac[i]), 0,
4613                                       &times, numBlocks, &pending)) {
4614                     ret = wc_HmacFinal(&hmac[i], digest[i]);
4615                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&hmac[i]),
4616                                             0, &times, &pending)) {
4617                         goto exit_hmac;
4618                     }
4619                 }
4620             } /* for i */
4621         } while (pending > 0);
4622     } while (bench_stats_sym_check(start));
4623 exit_hmac:
4624     bench_stats_sym_finish(label, doAsync, count, bench_size, start, ret);
4625 
4626 exit:
4627 
4628     for (i = 0; i < BENCH_MAX_PENDING; i++) {
4629         wc_HmacFree(&hmac[i]);
4630     }
4631 
4632 #ifdef WOLFSSL_ASYNC_CRYPT
4633     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
4634 #endif
4635 }
4636 
4637 #ifndef NO_MD5
4638 
bench_hmac_md5(int doAsync)4639 void bench_hmac_md5(int doAsync)
4640 {
4641     byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4642                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
4643 
4644     bench_hmac(doAsync, WC_MD5, WC_MD5_DIGEST_SIZE, key, sizeof(key),
4645                "HMAC-MD5");
4646 }
4647 
4648 #endif /* NO_MD5 */
4649 
4650 #ifndef NO_SHA
4651 
bench_hmac_sha(int doAsync)4652 void bench_hmac_sha(int doAsync)
4653 {
4654     byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4655                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4656                    0x0b, 0x0b, 0x0b, 0x0b };
4657 
4658     bench_hmac(doAsync, WC_SHA, WC_SHA_DIGEST_SIZE, key, sizeof(key),
4659                "HMAC-SHA");
4660 }
4661 
4662 #endif /* NO_SHA */
4663 
4664 #ifdef WOLFSSL_SHA224
4665 
bench_hmac_sha224(int doAsync)4666 void bench_hmac_sha224(int doAsync)
4667 {
4668     byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4669                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4670                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4671                    0x0b, 0x0b, 0x0b, 0x0b };
4672 
4673     bench_hmac(doAsync, WC_SHA224, WC_SHA224_DIGEST_SIZE, key, sizeof(key),
4674                "HMAC-SHA224");
4675 }
4676 
4677 #endif /* WOLFSSL_SHA224 */
4678 
4679 #ifndef NO_SHA256
4680 
bench_hmac_sha256(int doAsync)4681 void bench_hmac_sha256(int doAsync)
4682 {
4683     byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4684                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4685                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4686                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
4687 
4688     bench_hmac(doAsync, WC_SHA256, WC_SHA256_DIGEST_SIZE, key, sizeof(key),
4689                "HMAC-SHA256");
4690 }
4691 
4692 #endif /* NO_SHA256 */
4693 
4694 #ifdef WOLFSSL_SHA384
4695 
bench_hmac_sha384(int doAsync)4696 void bench_hmac_sha384(int doAsync)
4697 {
4698     byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4699                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4700                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4701                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4702                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4703                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
4704 
4705     bench_hmac(doAsync, WC_SHA384, WC_SHA384_DIGEST_SIZE, key, sizeof(key),
4706                "HMAC-SHA384");
4707 }
4708 
4709 #endif /* WOLFSSL_SHA384 */
4710 
4711 #ifdef WOLFSSL_SHA512
4712 
bench_hmac_sha512(int doAsync)4713 void bench_hmac_sha512(int doAsync)
4714 {
4715     byte key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4716                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4717                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4718                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4719                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4720                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4721                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
4722                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
4723 
4724     bench_hmac(doAsync, WC_SHA512, WC_SHA512_DIGEST_SIZE, key, sizeof(key),
4725                "HMAC-SHA512");
4726 }
4727 
4728 #endif /* WOLFSSL_SHA512 */
4729 
4730 #ifndef NO_PWDBASED
bench_pbkdf2(void)4731 void bench_pbkdf2(void)
4732 {
4733     double start;
4734     int    ret = 0, count = 0;
4735     const char* passwd32 = "passwordpasswordpasswordpassword";
4736     const byte salt32[] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06,
4737                             0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06,
4738                             0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06,
4739                             0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06 };
4740     byte derived[32];
4741 
4742     bench_stats_start(&count, &start);
4743     do {
4744         ret = wc_PBKDF2(derived, (const byte*)passwd32, (int)XSTRLEN(passwd32),
4745             salt32, (int)sizeof(salt32), 1000, 32, WC_SHA256);
4746         count++;
4747     } while (bench_stats_sym_check(start));
4748     bench_stats_sym_finish("PBKDF2", 32, count, 32, start, ret);
4749 }
4750 #endif /* !NO_PWDBASED */
4751 
4752 #endif /* NO_HMAC */
4753 
4754 #ifndef NO_RSA
4755 
4756 #if defined(WOLFSSL_KEY_GEN)
bench_rsaKeyGen_helper(int doAsync,int keySz)4757 static void bench_rsaKeyGen_helper(int doAsync, int keySz)
4758 {
4759     RsaKey genKey[BENCH_MAX_PENDING];
4760     double start;
4761     int    ret = 0, i, count = 0, times, pending = 0;
4762     const long rsa_e_val = WC_RSA_EXPONENT;
4763     const char**desc = bench_desc_words[lng_index];
4764 
4765     /* clear for done cleanup */
4766     XMEMSET(genKey, 0, sizeof(genKey));
4767 
4768     bench_stats_start(&count, &start);
4769     do {
4770         /* while free pending slots in queue, submit ops */
4771         for (times = 0; times < genTimes || pending > 0; ) {
4772             bench_async_poll(&pending);
4773 
4774             for (i = 0; i < BENCH_MAX_PENDING; i++) {
4775                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 0, &times, genTimes, &pending)) {
4776 
4777                     wc_FreeRsaKey(&genKey[i]);
4778                     ret = wc_InitRsaKey_ex(&genKey[i], HEAP_HINT,
4779                         doAsync ? devId : INVALID_DEVID);
4780                     if (ret < 0) {
4781                         goto exit;
4782                     }
4783 
4784                     ret = wc_MakeRsaKey(&genKey[i], keySz, rsa_e_val, &gRng);
4785                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 0, &times, &pending)) {
4786                         goto exit;
4787                     }
4788                 }
4789             } /* for i */
4790         } /* for times */
4791         count += times;
4792     } while (bench_stats_sym_check(start));
4793 exit:
4794     bench_stats_asym_finish("RSA", keySz, desc[2], doAsync, count, start, ret);
4795 
4796     /* cleanup */
4797     for (i = 0; i < BENCH_MAX_PENDING; i++) {
4798         wc_FreeRsaKey(&genKey[i]);
4799     }
4800 }
4801 
bench_rsaKeyGen(int doAsync)4802 void bench_rsaKeyGen(int doAsync)
4803 {
4804     int    k, keySz;
4805 #if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
4806     const int  keySizes[2] = {1024, 2048};
4807 #else
4808     const int  keySizes[1] = {2048};
4809 #endif
4810 
4811     for (k = 0; k < (int)(sizeof(keySizes)/sizeof(int)); k++) {
4812         keySz = keySizes[k];
4813         bench_rsaKeyGen_helper(doAsync, keySz);
4814     }
4815 }
4816 
4817 
bench_rsaKeyGen_size(int doAsync,int keySz)4818 void bench_rsaKeyGen_size(int doAsync, int keySz)
4819 {
4820     bench_rsaKeyGen_helper(doAsync, keySz);
4821 }
4822 #endif /* WOLFSSL_KEY_GEN */
4823 
4824 #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \
4825     !defined(USE_CERT_BUFFERS_3072)
4826     #if defined(WOLFSSL_MDK_SHELL)
4827         static char *certRSAname = "certs/rsa2048.der";
4828         /* set by shell command */
set_Bench_RSA_File(char * cert)4829         static void set_Bench_RSA_File(char * cert) { certRSAname = cert ; }
4830     #elif defined(FREESCALE_MQX)
4831         static char *certRSAname = "a:\\certs\\rsa2048.der";
4832     #else
4833         static const char *certRSAname = "certs/rsa2048.der";
4834     #endif
4835 #endif
4836 
4837 #define RSA_BUF_SIZE 384  /* for up to 3072 bit */
4838 
4839 #if defined(WOLFSSL_RSA_VERIFY_INLINE) || defined(WOLFSSL_RSA_PUBLIC_ONLY)
4840 #if defined(USE_CERT_BUFFERS_2048)
4841 static unsigned char rsa_2048_sig[] = {
4842     0x8c, 0x9e, 0x37, 0xbf, 0xc3, 0xa6, 0xba, 0x1c,
4843     0x53, 0x22, 0x40, 0x4b, 0x8b, 0x0d, 0x3c, 0x0e,
4844     0x2e, 0x8c, 0x31, 0x2c, 0x47, 0xbf, 0x03, 0x48,
4845     0x18, 0x46, 0x73, 0x8d, 0xd7, 0xdd, 0x17, 0x64,
4846     0x0d, 0x7f, 0xdc, 0x74, 0xed, 0x80, 0xc3, 0xe8,
4847     0x9a, 0x18, 0x33, 0xd4, 0xe6, 0xc5, 0xe1, 0x54,
4848     0x75, 0xd1, 0xbb, 0x40, 0xde, 0xa8, 0xb9, 0x1b,
4849     0x14, 0xe8, 0xc1, 0x39, 0xeb, 0xa0, 0x69, 0x8a,
4850     0xc6, 0x9b, 0xef, 0x53, 0xb5, 0x23, 0x2b, 0x78,
4851     0x06, 0x43, 0x37, 0x11, 0x81, 0x84, 0x73, 0x33,
4852     0x33, 0xfe, 0xf7, 0x5d, 0x2b, 0x84, 0xd6, 0x83,
4853     0xd6, 0xdd, 0x55, 0x33, 0xef, 0xd1, 0xf7, 0x12,
4854     0xb0, 0xc2, 0x0e, 0xb1, 0x78, 0xd4, 0xa8, 0xa3,
4855     0x25, 0xeb, 0xed, 0x9a, 0xb3, 0xee, 0xc3, 0x7e,
4856     0xce, 0x13, 0x18, 0x86, 0x31, 0xe1, 0xef, 0x01,
4857     0x0f, 0x6e, 0x67, 0x24, 0x74, 0xbd, 0x0b, 0x7f,
4858     0xa9, 0xca, 0x6f, 0xaa, 0x83, 0x28, 0x90, 0x40,
4859     0xf1, 0xb5, 0x10, 0x0e, 0x26, 0x03, 0x05, 0x5d,
4860     0x87, 0xb4, 0xe0, 0x4c, 0x98, 0xd8, 0xc6, 0x42,
4861     0x89, 0x77, 0xeb, 0xb6, 0xd4, 0xe6, 0x26, 0xf3,
4862     0x31, 0x25, 0xde, 0x28, 0x38, 0x58, 0xe8, 0x2c,
4863     0xf4, 0x56, 0x7c, 0xb6, 0xfd, 0x99, 0xb0, 0xb0,
4864     0xf4, 0x83, 0xb6, 0x74, 0xa9, 0x5b, 0x9f, 0xe8,
4865     0xe9, 0xf1, 0xa1, 0x2a, 0xbd, 0xf6, 0x83, 0x28,
4866     0x09, 0xda, 0xa6, 0xd6, 0xcd, 0x61, 0x60, 0xf7,
4867     0x13, 0x4e, 0x46, 0x57, 0x38, 0x1e, 0x11, 0x92,
4868     0x6b, 0x6b, 0xcf, 0xd3, 0xf4, 0x8b, 0x66, 0x03,
4869     0x25, 0xa3, 0x7a, 0x2f, 0xce, 0xc1, 0x85, 0xa5,
4870     0x48, 0x91, 0x8a, 0xb3, 0x4f, 0x5d, 0x98, 0xb1,
4871     0x69, 0x58, 0x47, 0x69, 0x0c, 0x52, 0xdc, 0x42,
4872     0x4c, 0xef, 0xe8, 0xd4, 0x4d, 0x6a, 0x33, 0x7d,
4873     0x9e, 0xd2, 0x51, 0xe6, 0x41, 0xbf, 0x4f, 0xa2
4874 };
4875 #elif defined(USE_CERT_BUFFERS_3072)
4876 static unsigned char rsa_3072_sig[] = {
4877     0x1a, 0xd6, 0x0d, 0xfd, 0xe3, 0x41, 0x95, 0x76,
4878     0x27, 0x16, 0x7d, 0xc7, 0x94, 0x16, 0xca, 0xa8,
4879     0x26, 0x08, 0xbe, 0x78, 0x87, 0x72, 0x4c, 0xd9,
4880     0xa7, 0xfc, 0x33, 0x77, 0x2d, 0x53, 0x07, 0xb5,
4881     0x8c, 0xce, 0x48, 0x17, 0x9b, 0xff, 0x9f, 0x9b,
4882     0x17, 0xc4, 0xbb, 0x72, 0xed, 0xdb, 0xa0, 0x34,
4883     0x69, 0x5b, 0xc7, 0x4e, 0xbf, 0xec, 0x13, 0xc5,
4884     0x98, 0x71, 0x9a, 0x4e, 0x18, 0x0e, 0xcb, 0xe7,
4885     0xc6, 0xd5, 0x21, 0x31, 0x7c, 0x0d, 0xae, 0x14,
4886     0x2b, 0x87, 0x4f, 0x77, 0x95, 0x2e, 0x26, 0xe2,
4887     0x83, 0xfe, 0x49, 0x1e, 0x87, 0x19, 0x4a, 0x63,
4888     0x73, 0x75, 0xf1, 0xf5, 0x71, 0xd2, 0xce, 0xd4,
4889     0x39, 0x2b, 0xd9, 0xe0, 0x76, 0x70, 0xc8, 0xf8,
4890     0xed, 0xdf, 0x90, 0x57, 0x17, 0xb9, 0x16, 0xf6,
4891     0xe9, 0x49, 0x48, 0xce, 0x5a, 0x8b, 0xe4, 0x84,
4892     0x7c, 0xf3, 0x31, 0x68, 0x97, 0x45, 0x68, 0x38,
4893     0x50, 0x3a, 0x70, 0xbd, 0xb3, 0xd3, 0xd2, 0xe0,
4894     0x56, 0x5b, 0xc2, 0x0c, 0x2c, 0x10, 0x70, 0x7b,
4895     0xd4, 0x99, 0xf9, 0x38, 0x31, 0xb1, 0x86, 0xa0,
4896     0x07, 0xf1, 0xf6, 0x53, 0xb0, 0x44, 0x82, 0x40,
4897     0xd2, 0xab, 0x0e, 0x71, 0x5d, 0xe1, 0xea, 0x3a,
4898     0x77, 0xc9, 0xef, 0xfe, 0x54, 0x65, 0xa3, 0x49,
4899     0xfd, 0xa5, 0x33, 0xaa, 0x16, 0x1a, 0x38, 0xe7,
4900     0xaa, 0xb7, 0x13, 0xb2, 0x3b, 0xc7, 0x00, 0x87,
4901     0x12, 0xfe, 0xfd, 0xf4, 0x55, 0x6d, 0x1d, 0x4a,
4902     0x0e, 0xad, 0xd0, 0x4c, 0x55, 0x91, 0x60, 0xd9,
4903     0xef, 0x74, 0x69, 0x22, 0x8c, 0x51, 0x65, 0xc2,
4904     0x04, 0xac, 0xd3, 0x8d, 0xf7, 0x35, 0x29, 0x13,
4905     0x6d, 0x61, 0x7c, 0x39, 0x2f, 0x41, 0x4c, 0xdf,
4906     0x38, 0xfd, 0x1a, 0x7d, 0x42, 0xa7, 0x6f, 0x3f,
4907     0x3d, 0x9b, 0xd1, 0x97, 0xab, 0xc0, 0xa7, 0x28,
4908     0x1c, 0xc0, 0x02, 0x26, 0xeb, 0xce, 0xf9, 0xe1,
4909     0x34, 0x45, 0xaf, 0xbf, 0x8d, 0xb8, 0xe0, 0xff,
4910     0xd9, 0x6f, 0x77, 0xf3, 0xf7, 0xed, 0x6a, 0xbb,
4911     0x03, 0x52, 0xfb, 0x38, 0xfc, 0xea, 0x9f, 0xc9,
4912     0x98, 0xed, 0x21, 0x45, 0xaf, 0x43, 0x2b, 0x64,
4913     0x96, 0x82, 0x30, 0xe9, 0xb4, 0x36, 0x89, 0x77,
4914     0x07, 0x4a, 0xc6, 0x1f, 0x38, 0x7a, 0xee, 0xb6,
4915     0x86, 0xf6, 0x2f, 0x03, 0xec, 0xa2, 0xe5, 0x48,
4916     0xe5, 0x5a, 0xf5, 0x1c, 0xd2, 0xd9, 0xd8, 0x2d,
4917     0x9d, 0x06, 0x07, 0xc9, 0x8b, 0x5d, 0xe0, 0x0f,
4918     0x5e, 0x0c, 0x53, 0x27, 0xff, 0x23, 0xee, 0xca,
4919     0x5e, 0x4d, 0xf1, 0x95, 0x77, 0x78, 0x1f, 0xf2,
4920     0x44, 0x5b, 0x7d, 0x01, 0x49, 0x61, 0x6f, 0x6d,
4921     0xbf, 0xf5, 0x19, 0x06, 0x39, 0xe9, 0xe9, 0x29,
4922     0xde, 0x47, 0x5e, 0x2e, 0x1f, 0x68, 0xf4, 0x32,
4923     0x5e, 0xe9, 0xd0, 0xa7, 0xb4, 0x2a, 0x45, 0xdf,
4924     0x15, 0x7d, 0x0d, 0x5b, 0xef, 0xc6, 0x23, 0xac
4925 };
4926 #else
4927     #error Not Supported Yet!
4928 #endif
4929 #endif /* WOLFSSL_RSA_VERIFY_INLINE || WOLFSSL_RSA_PUBLIC_ONLY */
4930 
bench_rsa_helper(int doAsync,RsaKey rsaKey[BENCH_MAX_PENDING],int rsaKeySz)4931 static void bench_rsa_helper(int doAsync, RsaKey rsaKey[BENCH_MAX_PENDING],
4932         int rsaKeySz)
4933 {
4934     int         ret = 0, i, times, count = 0, pending = 0;
4935     word32      idx = 0;
4936 #ifndef WOLFSSL_RSA_VERIFY_ONLY
4937     const char* messageStr = TEST_STRING;
4938     const int   len = (int)TEST_STRING_SZ;
4939 #endif
4940     double      start = 0.0f;
4941     const char**desc = bench_desc_words[lng_index];
4942 #ifndef WOLFSSL_RSA_VERIFY_ONLY
4943     WC_DECLARE_VAR(message, byte, TEST_STRING_SZ, HEAP_HINT);
4944 #endif
4945     #if !defined(WOLFSSL_MDK5_COMPLv5) && !defined(_WIN32_WCE)
4946     /* MDK5 compiler regard this as a executable statement, and does not allow declarations after the line. */
4947     WC_DECLARE_ARRAY_DYNAMIC_DEC(enc, byte, BENCH_MAX_PENDING, rsaKeySz, HEAP_HINT);
4948     #else
4949         byte* enc[BENCH_MAX_PENDING];
4950     #endif
4951     #if !defined(WOLFSSL_RSA_VERIFY_INLINE) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
4952         #if !defined(WOLFSSL_MDK5_COMPLv5) && !defined(_WIN32_WCE)
4953           /* MDK5 compiler regard this as a executable statement, and does not allow declarations after the line. */
4954             WC_DECLARE_ARRAY_DYNAMIC_DEC(out, byte, BENCH_MAX_PENDING, rsaKeySz, HEAP_HINT);
4955             #else
4956               byte* out[BENCH_MAX_PENDING];
4957         #endif
4958     #else
4959         byte* out[BENCH_MAX_PENDING];
4960     #endif
4961 
4962     WC_DECLARE_ARRAY_DYNAMIC_EXE(enc, byte, BENCH_MAX_PENDING, rsaKeySz, HEAP_HINT);
4963     #if !defined(WOLFSSL_RSA_VERIFY_INLINE) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
4964         WC_DECLARE_ARRAY_DYNAMIC_EXE(out, byte, BENCH_MAX_PENDING, rsaKeySz, HEAP_HINT);
4965         if (out[0] == NULL) {
4966             ret = MEMORY_E;
4967             goto exit;
4968         }
4969     #endif
4970     if (enc[0] == NULL) {
4971         ret = MEMORY_E;
4972         goto exit;
4973     }
4974 #ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
4975     if (message == NULL) {
4976         ret = MEMORY_E;
4977         goto exit;
4978     }
4979 #endif
4980 #ifndef WOLFSSL_RSA_VERIFY_ONLY
4981     XMEMCPY(message, messageStr, len);
4982 #endif
4983 
4984     if (!rsa_sign_verify) {
4985 #ifndef WOLFSSL_RSA_VERIFY_ONLY
4986         /* begin public RSA */
4987         bench_stats_start(&count, &start);
4988         do {
4989             for (times = 0; times < ntimes || pending > 0; ) {
4990                 bench_async_poll(&pending);
4991 
4992                 /* while free pending slots in queue, submit ops */
4993                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
4994                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&rsaKey[i]),
4995                                                  1, &times, ntimes, &pending)) {
4996                         ret = wc_RsaPublicEncrypt(message, (word32)len, enc[i],
4997                                                   rsaKeySz/8, &rsaKey[i],
4998                                                   GLOBAL_RNG);
4999                         if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(
5000                                             &rsaKey[i]), 1, &times, &pending)) {
5001                             goto exit_rsa_verify;
5002                         }
5003                     }
5004                 } /* for i */
5005             } /* for times */
5006             count += times;
5007         } while (bench_stats_sym_check(start));
5008 exit_rsa_verify:
5009         bench_stats_asym_finish("RSA", rsaKeySz, desc[0], doAsync, count,
5010                                                                     start, ret);
5011 #endif /* !WOLFSSL_RSA_VERIFY_ONLY */
5012 
5013 #ifndef WOLFSSL_RSA_PUBLIC_ONLY
5014         if (ret < 0) {
5015             goto exit;
5016         }
5017 
5018         /* capture resulting encrypt length */
5019         idx = (word32)(rsaKeySz/8);
5020 
5021         /* begin private async RSA */
5022         bench_stats_start(&count, &start);
5023         do {
5024             for (times = 0; times < ntimes || pending > 0; ) {
5025                 bench_async_poll(&pending);
5026 
5027                 /* while free pending slots in queue, submit ops */
5028                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
5029                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&rsaKey[i]),
5030                                                  1, &times, ntimes, &pending)) {
5031                         ret = wc_RsaPrivateDecrypt(enc[i], idx, out[i],
5032                                                        rsaKeySz/8, &rsaKey[i]);
5033                         if (!bench_async_handle(&ret,
5034                                                 BENCH_ASYNC_GET_DEV(&rsaKey[i]),
5035                                                 1, &times, &pending)) {
5036                             goto exit_rsa_pub;
5037                         }
5038                     }
5039                 } /* for i */
5040             } /* for times */
5041             count += times;
5042         } while (bench_stats_sym_check(start));
5043 exit_rsa_pub:
5044         bench_stats_asym_finish("RSA", rsaKeySz, desc[1], doAsync, count,
5045                                                                     start, ret);
5046 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
5047     }
5048     else {
5049 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
5050         /* begin RSA sign */
5051         bench_stats_start(&count, &start);
5052         do {
5053             for (times = 0; times < ntimes || pending > 0; ) {
5054                 bench_async_poll(&pending);
5055 
5056                 /* while free pending slots in queue, submit ops */
5057                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
5058                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&rsaKey[i]),
5059                                                  1, &times, ntimes, &pending)) {
5060                         ret = wc_RsaSSL_Sign(message, len, enc[i],
5061                                                 rsaKeySz/8, &rsaKey[i], &gRng);
5062                         if (!bench_async_handle(&ret,
5063                                                 BENCH_ASYNC_GET_DEV(&rsaKey[i]),
5064                                                 1, &times, &pending)) {
5065                             goto exit_rsa_sign;
5066                         }
5067                     }
5068                 } /* for i */
5069             } /* for times */
5070             count += times;
5071         } while (bench_stats_sym_check(start));
5072 exit_rsa_sign:
5073         bench_stats_asym_finish("RSA", rsaKeySz, desc[4], doAsync, count, start,
5074                                                                            ret);
5075 
5076         if (ret < 0) {
5077             goto exit;
5078         }
5079 #endif /* !WOLFSSL_RSA_PUBLIC_ONLY && !WOLFSSL_RSA_VERIFY_ONLY */
5080 
5081         /* capture resulting encrypt length */
5082         idx = rsaKeySz/8;
5083 
5084         /* begin RSA verify */
5085         bench_stats_start(&count, &start);
5086         do {
5087             for (times = 0; times < ntimes || pending > 0; ) {
5088                 bench_async_poll(&pending);
5089 
5090                 /* while free pending slots in queue, submit ops */
5091                 for (i = 0; i < BENCH_MAX_PENDING; i++) {
5092                     if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&rsaKey[i]),
5093                                                  1, &times, ntimes, &pending)) {
5094                     #if !defined(WOLFSSL_RSA_VERIFY_INLINE) && \
5095                         !defined(WOLFSSL_RSA_PUBLIC_ONLY)
5096                         ret = wc_RsaSSL_Verify(enc[i], idx, out[i],
5097                                                       rsaKeySz/8, &rsaKey[i]);
5098                     #elif defined(USE_CERT_BUFFERS_2048)
5099                         XMEMCPY(enc[i], rsa_2048_sig, sizeof(rsa_2048_sig));
5100                         idx = sizeof(rsa_2048_sig);
5101                         out[i] = NULL;
5102                         ret = wc_RsaSSL_VerifyInline(enc[i], idx, &out[i],
5103                                                                     &rsaKey[i]);
5104                         if (ret > 0)
5105                             ret = 0;
5106                     #elif defined(USE_CERT_BUFFERS_3072)
5107                         XMEMCPY(enc[i], rsa_3072_sig, sizeof(rsa_3072_sig));
5108                         idx = sizeof(rsa_3072_sig);
5109                         out[i] = NULL;
5110                         ret = wc_RsaSSL_VerifyInline(enc[i], idx, &out[i],
5111                                                                     &rsaKey[i]);
5112                         if (ret > 0)
5113                             ret = 0;
5114                     #endif
5115                         if (!bench_async_handle(&ret,
5116                                                 BENCH_ASYNC_GET_DEV(&rsaKey[i]),
5117                                                 1, &times, &pending)) {
5118                             goto exit_rsa_verifyinline;
5119                         }
5120                     }
5121                 } /* for i */
5122             } /* for times */
5123             count += times;
5124         } while (bench_stats_sym_check(start));
5125 exit_rsa_verifyinline:
5126         bench_stats_asym_finish("RSA", rsaKeySz, desc[5], doAsync, count,
5127                                                                     start, ret);
5128     }
5129 
5130 exit:
5131 
5132     WC_FREE_ARRAY_DYNAMIC(enc, BENCH_MAX_PENDING, HEAP_HINT);
5133 #if !defined(WOLFSSL_RSA_VERIFY_INLINE) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
5134     WC_FREE_ARRAY_DYNAMIC(out, BENCH_MAX_PENDING, HEAP_HINT);
5135 #endif
5136     WC_FREE_VAR(message, HEAP_HINT);
5137 }
5138 
bench_rsa(int doAsync)5139 void bench_rsa(int doAsync)
5140 {
5141     int         i;
5142     RsaKey      rsaKey[BENCH_MAX_PENDING];
5143     int         ret = 0;
5144     int         rsaKeySz = 0;
5145     const byte* tmp;
5146     size_t      bytes;
5147 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
5148     word32      idx;
5149 #endif
5150 
5151 #ifdef USE_CERT_BUFFERS_1024
5152     tmp = rsa_key_der_1024;
5153     bytes = (size_t)sizeof_rsa_key_der_1024;
5154     rsaKeySz = 1024;
5155 #elif defined(USE_CERT_BUFFERS_2048)
5156     tmp = rsa_key_der_2048;
5157     bytes = (size_t)sizeof_rsa_key_der_2048;
5158     rsaKeySz = 2048;
5159 #elif defined(USE_CERT_BUFFERS_3072)
5160     tmp = rsa_key_der_3072;
5161     bytes = (size_t)sizeof_rsa_key_der_3072;
5162     rsaKeySz = 3072;
5163 #else
5164     #error "need a cert buffer size"
5165 #endif /* USE_CERT_BUFFERS */
5166 
5167     /* clear for done cleanup */
5168     XMEMSET(rsaKey, 0, sizeof(rsaKey));
5169 
5170     /* init keys */
5171     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5172         /* setup an async context for each key */
5173         ret = wc_InitRsaKey_ex(&rsaKey[i], HEAP_HINT,
5174                                doAsync ? devId : INVALID_DEVID);
5175         if (ret < 0) {
5176             goto exit_bench_rsa;
5177         }
5178 
5179 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
5180     #ifdef WC_RSA_BLINDING
5181         ret = wc_RsaSetRNG(&rsaKey[i], &gRng);
5182         if (ret != 0)
5183             goto exit_bench_rsa;
5184     #endif
5185 #endif
5186 
5187 #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)
5188         /* decode the private key */
5189         idx = 0;
5190         if ((ret = wc_RsaPrivateKeyDecode(tmp, &idx, &rsaKey[i],
5191                                                         (word32)bytes)) != 0) {
5192             printf("wc_RsaPrivateKeyDecode failed! %d\n", ret);
5193             goto exit_bench_rsa;
5194         }
5195 #elif defined(WOLFSSL_PUBLIC_MP)
5196         /* get offset to public portion of the RSA key */
5197     #ifdef USE_CERT_BUFFERS_1024
5198         bytes = 11;
5199     #elif defined(USE_CERT_BUFFERS_2048) || defined(USE_CERT_BUFFERS_3072)
5200         bytes = 12;
5201     #endif
5202         ret = mp_read_unsigned_bin(&rsaKey[i].n, &tmp[bytes], rsaKeySz/8);
5203         if (ret != 0) {
5204             printf("wc_RsaPrivateKeyDecode failed! %d\n", ret);
5205             goto exit_bench_rsa;
5206         }
5207         ret = mp_set_int(&rsaKey[i].e, WC_RSA_EXPONENT);
5208         if (ret != 0) {
5209             printf("wc_RsaPrivateKeyDecode failed! %d\n", ret);
5210             goto exit_bench_rsa;
5211         }
5212 #else
5213         /* Note: To benchmark public only define WOLFSSL_PUBLIC_MP */
5214         rsaKeySz = 0;
5215 #endif
5216     }
5217 
5218     if (rsaKeySz > 0) {
5219         bench_rsa_helper(doAsync, rsaKey, rsaKeySz);
5220     }
5221 
5222     (void)bytes;
5223     (void)tmp;
5224 
5225 exit_bench_rsa:
5226     /* cleanup */
5227     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5228         wc_FreeRsaKey(&rsaKey[i]);
5229     }
5230 }
5231 
5232 
5233 #ifdef WOLFSSL_KEY_GEN
5234 /* bench any size of RSA key */
bench_rsa_key(int doAsync,int rsaKeySz)5235 void bench_rsa_key(int doAsync, int rsaKeySz)
5236 {
5237     int     ret = 0, i, pending = 0;
5238     RsaKey  rsaKey[BENCH_MAX_PENDING];
5239     int     isPending[BENCH_MAX_PENDING];
5240     long    exp = 65537l;
5241 
5242     /* clear for done cleanup */
5243     XMEMSET(rsaKey, 0, sizeof(rsaKey));
5244     XMEMSET(isPending, 0, sizeof(isPending));
5245 
5246     /* init keys */
5247     do {
5248         pending = 0;
5249         for (i = 0; i < BENCH_MAX_PENDING; i++) {
5250             if (!isPending[i]) { /* if making the key is pending then just call
5251                                   * wc_MakeRsaKey again */
5252                 /* setup an async context for each key */
5253                 if (wc_InitRsaKey_ex(&rsaKey[i], HEAP_HINT,
5254                                      doAsync ? devId : INVALID_DEVID) < 0) {
5255                     goto exit_bench_rsa_key;
5256                 }
5257 
5258             #ifdef WC_RSA_BLINDING
5259                 ret = wc_RsaSetRNG(&rsaKey[i], &gRng);
5260                 if (ret != 0)
5261                     goto exit_bench_rsa_key;
5262             #endif
5263             }
5264 
5265             /* create the RSA key */
5266             ret = wc_MakeRsaKey(&rsaKey[i], rsaKeySz, exp, &gRng);
5267             if (ret == WC_PENDING_E) {
5268                 isPending[i] = 1;
5269                 pending      = 1;
5270             }
5271             else if (ret != 0) {
5272                 printf("wc_MakeRsaKey failed! %d\n", ret);
5273                 goto exit_bench_rsa_key;
5274             }
5275         } /* for i */
5276     } while (pending > 0);
5277 
5278     bench_rsa_helper(doAsync, rsaKey, rsaKeySz);
5279 exit_bench_rsa_key:
5280 
5281     /* cleanup */
5282     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5283         wc_FreeRsaKey(&rsaKey[i]);
5284     }
5285 }
5286 #endif /* WOLFSSL_KEY_GEN */
5287 #endif /* !NO_RSA */
5288 
5289 
5290 #ifndef NO_DH
5291 
5292 #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \
5293     !defined(USE_CERT_BUFFERS_3072)
5294     #if defined(WOLFSSL_MDK_SHELL)
5295         static char *certDHname = "certs/dh2048.der";
5296         /* set by shell command */
set_Bench_DH_File(char * cert)5297         void set_Bench_DH_File(char * cert) { certDHname = cert ; }
5298     #elif defined(FREESCALE_MQX)
5299         static char *certDHname = "a:\\certs\\dh2048.der";
5300     #elif defined(NO_ASN)
5301         /* do nothing, but don't need a file */
5302     #else
5303         static const char *certDHname = "certs/dh2048.der";
5304     #endif
5305 #endif
5306 
5307 #ifdef HAVE_FFDHE_4096
5308 #define BENCH_DH_KEY_SIZE  512 /* for 4096 bit */
5309 #else
5310 #define BENCH_DH_KEY_SIZE  384 /* for 3072 bit */
5311 #endif
5312 #define BENCH_DH_PRIV_SIZE (BENCH_DH_KEY_SIZE/8)
5313 
bench_dh(int doAsync)5314 void bench_dh(int doAsync)
5315 {
5316     int    ret = 0, i;
5317     int    count = 0, times, pending = 0;
5318     const byte* tmp = NULL;
5319     double start = 0.0f;
5320     DhKey  dhKey[BENCH_MAX_PENDING];
5321     int    dhKeySz = BENCH_DH_KEY_SIZE * 8; /* used in printf */
5322     const char**desc = bench_desc_words[lng_index];
5323 #ifndef NO_ASN
5324     size_t bytes = 0;
5325     word32 idx;
5326 #endif
5327     word32 pubSz[BENCH_MAX_PENDING];
5328     word32 privSz[BENCH_MAX_PENDING];
5329     word32 pubSz2 = BENCH_DH_KEY_SIZE;
5330     word32 privSz2 = BENCH_DH_PRIV_SIZE;
5331     word32 agreeSz[BENCH_MAX_PENDING];
5332 #if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072)
5333 #ifdef HAVE_PUBLIC_FFDHE
5334     const DhParams *params = NULL;
5335 #else
5336     int paramName = 0;
5337 #endif
5338 #endif
5339 
5340     WC_DECLARE_ARRAY(pub, byte, BENCH_MAX_PENDING, BENCH_DH_KEY_SIZE, HEAP_HINT);
5341     WC_DECLARE_VAR(pub2, byte, BENCH_DH_KEY_SIZE, HEAP_HINT);
5342     WC_DECLARE_ARRAY(agree, byte, BENCH_MAX_PENDING, BENCH_DH_KEY_SIZE, HEAP_HINT);
5343     WC_DECLARE_ARRAY(priv, byte, BENCH_MAX_PENDING, BENCH_DH_PRIV_SIZE, HEAP_HINT);
5344     WC_DECLARE_VAR(priv2, byte, BENCH_DH_PRIV_SIZE, HEAP_HINT);
5345 #ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC
5346     if (pub[0] == NULL || pub2 == NULL || agree[0] == NULL || priv[0] == NULL || priv2 == NULL) {
5347         ret = MEMORY_E;
5348         goto exit;
5349     }
5350 #endif
5351 
5352     (void)tmp;
5353 
5354     if (!use_ffdhe) {
5355 #if defined(NO_ASN)
5356         dhKeySz = 1024;
5357         /* do nothing, but don't use default FILE */
5358 #elif defined(USE_CERT_BUFFERS_1024)
5359         tmp = dh_key_der_1024;
5360         bytes = (size_t)sizeof_dh_key_der_1024;
5361         dhKeySz = 1024;
5362 #elif defined(USE_CERT_BUFFERS_2048)
5363         tmp = dh_key_der_2048;
5364         bytes = (size_t)sizeof_dh_key_der_2048;
5365         dhKeySz = 2048;
5366 #elif defined(USE_CERT_BUFFERS_3072)
5367         tmp = dh_key_der_3072;
5368         bytes = (size_t)sizeof_dh_key_der_3072;
5369         dhKeySz = 3072;
5370 #else
5371     #error "need to define a cert buffer size"
5372 #endif /* USE_CERT_BUFFERS */
5373     }
5374 #ifdef HAVE_FFDHE_2048
5375     else if (use_ffdhe == 2048) {
5376 #ifdef HAVE_PUBLIC_FFDHE
5377         params = wc_Dh_ffdhe2048_Get();
5378 #else
5379         paramName = WC_FFDHE_2048;
5380 #endif
5381         dhKeySz = 2048;
5382     }
5383 #endif
5384 #ifdef HAVE_FFDHE_3072
5385     else if (use_ffdhe == 3072) {
5386 #ifdef HAVE_PUBLIC_FFDHE
5387         params = wc_Dh_ffdhe3072_Get();
5388 #else
5389         paramName = WC_FFDHE_3072;
5390 #endif
5391         dhKeySz = 3072;
5392     }
5393 #endif
5394 #ifdef HAVE_FFDHE_4096
5395     else if (use_ffdhe == 4096) {
5396 #ifdef HAVE_PUBLIC_FFDHE
5397         params = wc_Dh_ffdhe4096_Get();
5398 #else
5399         paramName = WC_FFDHE_4096;
5400 #endif
5401         dhKeySz = 4096;
5402     }
5403 #endif
5404 
5405     /* clear for done cleanup */
5406     XMEMSET(dhKey, 0, sizeof(dhKey));
5407 
5408     /* init keys */
5409     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5410         /* setup an async context for each key */
5411         ret = wc_InitDhKey_ex(&dhKey[i], HEAP_HINT,
5412                         doAsync ? devId : INVALID_DEVID);
5413         if (ret != 0)
5414             goto exit;
5415 
5416         /* setup key */
5417         if (!use_ffdhe) {
5418     #ifdef NO_ASN
5419             ret = wc_DhSetKey(&dhKey[i], dh_p, sizeof(dh_p), dh_g,
5420                                                                   sizeof(dh_g));
5421     #else
5422             idx = 0;
5423             ret = wc_DhKeyDecode(tmp, &idx, &dhKey[i], (word32)bytes);
5424     #endif
5425         }
5426     #if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072)
5427     #ifdef HAVE_PUBLIC_FFDHE
5428         else if (params != NULL) {
5429             ret = wc_DhSetKey(&dhKey[i], params->p, params->p_len, params->g,
5430                                                                  params->g_len);
5431         }
5432     #else
5433         else if (paramName != 0) {
5434             ret = wc_DhSetNamedKey(&dhKey[i], paramName);
5435         }
5436     #endif
5437     #endif
5438         if (ret != 0) {
5439             printf("DhKeyDecode failed %d, can't benchmark\n", ret);
5440             goto exit;
5441         }
5442     }
5443 
5444     /* Key Gen */
5445     bench_stats_start(&count, &start);
5446     PRIVATE_KEY_UNLOCK();
5447     do {
5448         /* while free pending slots in queue, submit ops */
5449         for (times = 0; times < genTimes || pending > 0; ) {
5450             bench_async_poll(&pending);
5451 
5452             for (i = 0; i < BENCH_MAX_PENDING; i++) {
5453                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&dhKey[i]), 0, &times, genTimes, &pending)) {
5454                     privSz[i] = BENCH_DH_PRIV_SIZE;
5455                     pubSz[i] = BENCH_DH_KEY_SIZE;
5456                     ret = wc_DhGenerateKeyPair(&dhKey[i], &gRng, priv[i], &privSz[i],
5457                         pub[i], &pubSz[i]);
5458                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&dhKey[i]), 0, &times, &pending)) {
5459                         goto exit_dh_gen;
5460                     }
5461                 }
5462             } /* for i */
5463         } /* for times */
5464         count += times;
5465     } while (bench_stats_sym_check(start));
5466     PRIVATE_KEY_LOCK();
5467 exit_dh_gen:
5468     bench_stats_asym_finish("DH", dhKeySz, desc[2], doAsync, count, start, ret);
5469 
5470     if (ret < 0) {
5471         goto exit;
5472     }
5473 
5474     /* Generate key to use as other public */
5475     PRIVATE_KEY_UNLOCK();
5476     ret = wc_DhGenerateKeyPair(&dhKey[0], &gRng, priv2, &privSz2, pub2, &pubSz2);
5477     PRIVATE_KEY_LOCK();
5478 #ifdef WOLFSSL_ASYNC_CRYPT
5479     ret = wc_AsyncWait(ret, &dhKey[0].asyncDev, WC_ASYNC_FLAG_NONE);
5480 #endif
5481 
5482     /* Key Agree */
5483     bench_stats_start(&count, &start);
5484     PRIVATE_KEY_UNLOCK();
5485     do {
5486         for (times = 0; times < agreeTimes || pending > 0; ) {
5487             bench_async_poll(&pending);
5488 
5489             /* while free pending slots in queue, submit ops */
5490             for (i = 0; i < BENCH_MAX_PENDING; i++) {
5491                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&dhKey[i]), 0, &times, agreeTimes, &pending)) {
5492                     ret = wc_DhAgree(&dhKey[i], agree[i], &agreeSz[i], priv[i], privSz[i],
5493                         pub2, pubSz2);
5494                     if (!bench_async_handle(&ret, BENCH_ASYNC_GET_DEV(&dhKey[i]), 0, &times, &pending)) {
5495                         goto exit;
5496                     }
5497                 }
5498             } /* for i */
5499         } /* for times */
5500         count += times;
5501     } while (bench_stats_sym_check(start));
5502     PRIVATE_KEY_LOCK();
5503 exit:
5504     bench_stats_asym_finish("DH", dhKeySz, desc[3], doAsync, count, start, ret);
5505 
5506     /* cleanup */
5507     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5508         wc_FreeDhKey(&dhKey[i]);
5509     }
5510 
5511     WC_FREE_ARRAY(pub, BENCH_MAX_PENDING, HEAP_HINT);
5512     WC_FREE_VAR(pub2, HEAP_HINT);
5513     WC_FREE_ARRAY(priv, BENCH_MAX_PENDING, HEAP_HINT);
5514     WC_FREE_VAR(priv2, HEAP_HINT);
5515     WC_FREE_ARRAY(agree, BENCH_MAX_PENDING, HEAP_HINT);
5516 }
5517 #endif /* !NO_DH */
5518 
5519 #ifdef HAVE_ECC
5520 
5521 /* +8 for 'ECDSA [%s]' and null terminator */
5522 #define BENCH_ECC_NAME_SZ (ECC_MAXNAME + 8)
5523 
5524 /* run all benchmarks on a curve */
bench_ecc_curve(int curveId)5525 void bench_ecc_curve(int curveId)
5526 {
5527     if (bench_all || (bench_asym_algs & BENCH_ECC_MAKEKEY)) {
5528     #ifndef NO_SW_BENCH
5529         bench_eccMakeKey(0, curveId);
5530     #endif
5531     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
5532         !defined(NO_HW_BENCH)
5533         bench_eccMakeKey(1, curveId);
5534     #endif
5535     }
5536     if (bench_all || (bench_asym_algs & BENCH_ECC)) {
5537     #ifndef NO_SW_BENCH
5538         bench_ecc(0, curveId);
5539     #endif
5540     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
5541         !defined(NO_HW_BENCH)
5542         bench_ecc(1, curveId);
5543     #endif
5544     }
5545     #ifdef HAVE_ECC_ENCRYPT
5546     if (bench_all || (bench_asym_algs & BENCH_ECC_ENCRYPT))
5547         bench_eccEncrypt(curveId);
5548     #endif
5549 }
5550 
5551 
bench_eccMakeKey(int doAsync,int curveId)5552 void bench_eccMakeKey(int doAsync, int curveId)
5553 {
5554     int ret = 0, i, times, count, pending = 0;
5555     int deviceID;
5556     int keySize;
5557     ecc_key genKey[BENCH_MAX_PENDING];
5558     char name[BENCH_ECC_NAME_SZ];
5559     double start;
5560     const char**desc = bench_desc_words[lng_index];
5561 
5562 #ifdef WOLFSSL_ASYNC_CRYPT
5563     deviceID = doAsync ? devId : INVALID_DEVID;
5564 #else
5565     deviceID = devId;
5566 #endif
5567 
5568     keySize = wc_ecc_get_curve_size_from_id(curveId);
5569 
5570     /* clear for done cleanup */
5571     XMEMSET(&genKey, 0, sizeof(genKey));
5572 
5573     /* ECC Make Key */
5574     bench_stats_start(&count, &start);
5575     do {
5576         /* while free pending slots in queue, submit ops */
5577         for (times = 0; times < genTimes || pending > 0; ) {
5578             bench_async_poll(&pending);
5579 
5580             for (i = 0; i < BENCH_MAX_PENDING; i++) {
5581                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 0,
5582                             &times, genTimes, &pending)) {
5583 
5584                     wc_ecc_free(&genKey[i]);
5585                     ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, deviceID);
5586                     if (ret < 0) {
5587                         goto exit;
5588                     }
5589 
5590                     ret = wc_ecc_make_key_ex(&gRng, keySize, &genKey[i],
5591                             curveId);
5592                     if (!bench_async_handle(&ret,
5593                                 BENCH_ASYNC_GET_DEV(&genKey[i]), 0, &times,
5594                                 &pending)) {
5595                         goto exit;
5596                     }
5597                 }
5598             } /* for i */
5599         } /* for times */
5600         count += times;
5601     } while (bench_stats_sym_check(start));
5602 exit:
5603     XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECC   [%15s]",
5604             wc_ecc_get_name(curveId));
5605     bench_stats_asym_finish(name, keySize * 8, desc[2], doAsync, count, start,
5606             ret);
5607 
5608     /* cleanup */
5609     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5610         wc_ecc_free(&genKey[i]);
5611     }
5612 }
5613 
5614 
bench_ecc(int doAsync,int curveId)5615 void bench_ecc(int doAsync, int curveId)
5616 {
5617     int ret = 0, i, times, count, pending = 0;
5618     int deviceID;
5619     int  keySize;
5620     char name[BENCH_ECC_NAME_SZ];
5621     ecc_key genKey[BENCH_MAX_PENDING];
5622 #ifdef HAVE_ECC_DHE
5623     ecc_key genKey2[BENCH_MAX_PENDING];
5624 #endif
5625 #if !defined(NO_ASN) && defined(HAVE_ECC_SIGN)
5626 #ifdef HAVE_ECC_VERIFY
5627     int    verify[BENCH_MAX_PENDING];
5628 #endif
5629 #endif
5630     word32 x[BENCH_MAX_PENDING];
5631     double start = 0;
5632     const char**desc = bench_desc_words[lng_index];
5633 
5634 #ifdef HAVE_ECC_DHE
5635     WC_DECLARE_ARRAY(shared, byte, BENCH_MAX_PENDING, MAX_ECC_BYTES, HEAP_HINT);
5636 #endif
5637 #if !defined(NO_ASN) && defined(HAVE_ECC_SIGN)
5638     WC_DECLARE_ARRAY(sig, byte, BENCH_MAX_PENDING, ECC_MAX_SIG_SIZE, HEAP_HINT);
5639     WC_DECLARE_ARRAY(digest, byte, BENCH_MAX_PENDING, MAX_ECC_BYTES, HEAP_HINT);
5640 #endif
5641 
5642 #ifdef WOLFSSL_ASYNC_CRYPT
5643     deviceID = doAsync ? devId : INVALID_DEVID;
5644 #else
5645     deviceID = devId;
5646 #endif
5647 
5648     /* clear for done cleanup */
5649     XMEMSET(&genKey, 0, sizeof(genKey));
5650 #ifdef HAVE_ECC_DHE
5651     XMEMSET(&genKey2, 0, sizeof(genKey2));
5652 #endif
5653     keySize = wc_ecc_get_curve_size_from_id(curveId);
5654 
5655     /* init keys */
5656     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5657         /* setup an context for each key */
5658         if ((ret = wc_ecc_init_ex(&genKey[i], HEAP_HINT, deviceID)) < 0) {
5659             goto exit;
5660         }
5661         ret = wc_ecc_make_key_ex(&gRng, keySize, &genKey[i], curveId);
5662     #ifdef WOLFSSL_ASYNC_CRYPT
5663         ret = wc_AsyncWait(ret, &genKey[i].asyncDev, WC_ASYNC_FLAG_NONE);
5664     #endif
5665         if (ret < 0) {
5666             goto exit;
5667         }
5668 
5669     #ifdef HAVE_ECC_DHE
5670         if ((ret = wc_ecc_init_ex(&genKey2[i], HEAP_HINT, deviceID)) < 0) {
5671             goto exit;
5672         }
5673         if ((ret = wc_ecc_make_key_ex(&gRng, keySize, &genKey2[i],
5674                     curveId)) > 0) {
5675             goto exit;
5676         }
5677     #endif
5678     }
5679 
5680 #ifdef HAVE_ECC_DHE
5681 #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
5682     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
5683     !defined(HAVE_SELFTEST)
5684     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5685         (void)wc_ecc_set_rng(&genKey[i], &gRng);
5686     }
5687 #endif
5688 
5689     /* ECC Shared Secret */
5690     bench_stats_start(&count, &start);
5691     PRIVATE_KEY_UNLOCK();
5692     do {
5693         for (times = 0; times < agreeTimes || pending > 0; ) {
5694             bench_async_poll(&pending);
5695 
5696             /* while free pending slots in queue, submit ops */
5697             for (i = 0; i < BENCH_MAX_PENDING; i++) {
5698                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 1,
5699                             &times, agreeTimes, &pending)) {
5700                     x[i] = (word32)keySize;
5701                     ret = wc_ecc_shared_secret(&genKey[i], &genKey2[i],
5702                             shared[i], &x[i]);
5703                     if (!bench_async_handle(&ret,
5704                                 BENCH_ASYNC_GET_DEV(&genKey[i]), 1, &times,
5705                                 &pending)) {
5706                         goto exit_ecdhe;
5707                     }
5708                 }
5709             } /* for i */
5710         } /* for times */
5711         count += times;
5712     } while (bench_stats_sym_check(start));
5713     PRIVATE_KEY_UNLOCK();
5714 exit_ecdhe:
5715     XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDHE [%15s]", wc_ecc_get_name(curveId));
5716 
5717     bench_stats_asym_finish(name, keySize * 8, desc[3], doAsync, count, start,
5718             ret);
5719 
5720     if (ret < 0) {
5721         goto exit;
5722     }
5723 #endif /* HAVE_ECC_DHE */
5724 
5725 #if !defined(NO_ASN) && defined(HAVE_ECC_SIGN)
5726 
5727     /* Init digest to sign */
5728     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5729         for (count = 0; count < keySize; count++) {
5730             digest[i][count] = (byte)count;
5731         }
5732     }
5733 
5734     /* ECC Sign */
5735     bench_stats_start(&count, &start);
5736     do {
5737         for (times = 0; times < agreeTimes || pending > 0; ) {
5738             bench_async_poll(&pending);
5739 
5740             /* while free pending slots in queue, submit ops */
5741             for (i = 0; i < BENCH_MAX_PENDING; i++) {
5742                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 1,
5743                             &times, agreeTimes, &pending)) {
5744                     if (genKey[i].state == 0)
5745                         x[i] = ECC_MAX_SIG_SIZE;
5746                     ret = wc_ecc_sign_hash(digest[i], (word32)keySize, sig[i],
5747                             &x[i], &gRng, &genKey[i]);
5748                     if (!bench_async_handle(&ret,
5749                                 BENCH_ASYNC_GET_DEV(&genKey[i]), 1, &times,
5750                                 &pending)) {
5751                         goto exit_ecdsa_sign;
5752                     }
5753                 }
5754             } /* for i */
5755         } /* for times */
5756         count += times;
5757     } while (bench_stats_sym_check(start));
5758 exit_ecdsa_sign:
5759     XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDSA [%15s]", wc_ecc_get_name(curveId));
5760 
5761     bench_stats_asym_finish(name, keySize * 8, desc[4], doAsync, count, start,
5762             ret);
5763 
5764     if (ret < 0) {
5765         goto exit;
5766     }
5767 
5768 #ifdef HAVE_ECC_VERIFY
5769 
5770     /* ECC Verify */
5771     bench_stats_start(&count, &start);
5772     do {
5773         for (times = 0; times < agreeTimes || pending > 0; ) {
5774             bench_async_poll(&pending);
5775 
5776             /* while free pending slots in queue, submit ops */
5777             for (i = 0; i < BENCH_MAX_PENDING; i++) {
5778                 if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(&genKey[i]), 1,
5779                             &times, agreeTimes, &pending)) {
5780                     if (genKey[i].state == 0)
5781                         verify[i] = 0;
5782                     ret = wc_ecc_verify_hash(sig[i], x[i], digest[i],
5783                                        (word32)keySize, &verify[i], &genKey[i]);
5784                     if (!bench_async_handle(&ret,
5785                                 BENCH_ASYNC_GET_DEV(&genKey[i]), 1, &times,
5786                                 &pending)) {
5787                         goto exit_ecdsa_verify;
5788                     }
5789                 }
5790             } /* for i */
5791         } /* for times */
5792         count += times;
5793     } while (bench_stats_sym_check(start));
5794 exit_ecdsa_verify:
5795     XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECDSA [%15s]", wc_ecc_get_name(curveId));
5796 
5797     bench_stats_asym_finish(name, keySize * 8, desc[5], doAsync, count, start,
5798             ret);
5799 #endif /* HAVE_ECC_VERIFY */
5800 #endif /* !NO_ASN && HAVE_ECC_SIGN */
5801 
5802 exit:
5803 
5804     /* cleanup */
5805     for (i = 0; i < BENCH_MAX_PENDING; i++) {
5806         wc_ecc_free(&genKey[i]);
5807     #ifdef HAVE_ECC_DHE
5808         wc_ecc_free(&genKey2[i]);
5809     #endif
5810     }
5811 
5812 #ifdef HAVE_ECC_DHE
5813     WC_FREE_ARRAY(shared, BENCH_MAX_PENDING, HEAP_HINT);
5814 #endif
5815 #if !defined(NO_ASN) && defined(HAVE_ECC_SIGN)
5816     WC_FREE_ARRAY(sig, BENCH_MAX_PENDING, HEAP_HINT);
5817     WC_FREE_ARRAY(digest, BENCH_MAX_PENDING, HEAP_HINT);
5818 #endif
5819 
5820     (void)doAsync;
5821     (void)pending;
5822     (void)x;
5823     (void)count;
5824     (void)times;
5825     (void)desc;
5826     (void)start;
5827     (void)name;
5828 }
5829 
5830 
5831 #ifdef HAVE_ECC_ENCRYPT
bench_eccEncrypt(int curveId)5832 void bench_eccEncrypt(int curveId)
5833 {
5834     ecc_key userA, userB;
5835     int     keySize;
5836     byte    msg[48];
5837     byte    out[sizeof(msg) + WC_SHA256_DIGEST_SIZE + (MAX_ECC_BITS+3)/4 + 2];
5838     word32  outSz   = sizeof(out);
5839     word32  bench_plainSz = BENCH_SIZE;
5840     int     ret, i, count;
5841     double start;
5842     const char**desc = bench_desc_words[lng_index];
5843     char name[BENCH_ECC_NAME_SZ];
5844 
5845     keySize = wc_ecc_get_curve_size_from_id(curveId);
5846     ret = wc_ecc_init_ex(&userA, HEAP_HINT, devId);
5847     if (ret != 0) {
5848         printf("wc_ecc_encrypt make key A failed: %d\n", ret);
5849         return;
5850     }
5851 
5852     ret = wc_ecc_init_ex(&userB, HEAP_HINT, devId);
5853     if (ret != 0) {
5854         printf("wc_ecc_encrypt make key B failed: %d\n", ret);
5855         wc_ecc_free(&userA);
5856         return;
5857     }
5858 
5859 #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \
5860     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \
5861     !defined(HAVE_SELFTEST)
5862     ret = wc_ecc_set_rng(&userA, &gRng);
5863     if (ret != 0) {
5864         goto exit;
5865     }
5866     ret = wc_ecc_set_rng(&userB, &gRng);
5867     if (ret != 0) {
5868         goto exit;
5869     }
5870 #endif
5871 
5872     ret = wc_ecc_make_key_ex(&gRng, keySize, &userA, curveId);
5873 #ifdef WOLFSSL_ASYNC_CRYPT
5874     ret = wc_AsyncWait(ret, &userA.asyncDev, WC_ASYNC_FLAG_NONE);
5875 #endif
5876     if (ret != 0)
5877         goto exit;
5878     ret = wc_ecc_make_key_ex(&gRng, keySize, &userB, curveId);
5879 #ifdef WOLFSSL_ASYNC_CRYPT
5880     ret = wc_AsyncWait(ret, &userB.asyncDev, WC_ASYNC_FLAG_NONE);
5881 #endif
5882     if (ret != 0)
5883         goto exit;
5884 
5885     for (i = 0; i < (int)sizeof(msg); i++)
5886         msg[i] = i;
5887 
5888     bench_stats_start(&count, &start);
5889     do {
5890         for (i = 0; i < ntimes; i++) {
5891             /* encrypt msg to B */
5892             ret = wc_ecc_encrypt(&userA, &userB, msg, sizeof(msg), out, &outSz,
5893                     NULL);
5894             if (ret != 0) {
5895                 printf("wc_ecc_encrypt failed! %d\n", ret);
5896                 goto exit_enc;
5897             }
5898         }
5899         count += i;
5900     } while (bench_stats_sym_check(start));
5901 exit_enc:
5902     XSNPRINTF(name, BENCH_ECC_NAME_SZ, "ECC   [%15s]", wc_ecc_get_name(curveId));
5903     bench_stats_asym_finish(name, keySize * 8, desc[6], 0, count, start, ret);
5904 
5905     bench_stats_start(&count, &start);
5906     do {
5907         for (i = 0; i < ntimes; i++) {
5908             /* decrypt msg from A */
5909             ret = wc_ecc_decrypt(&userB, &userA, out, outSz, bench_plain,
5910                     &bench_plainSz, NULL);
5911             if (ret != 0) {
5912                 printf("wc_ecc_decrypt failed! %d\n", ret);
5913                 goto exit_dec;
5914             }
5915         }
5916         count += i;
5917     } while (bench_stats_sym_check(start));
5918 exit_dec:
5919     bench_stats_asym_finish(name, keySize * 8, desc[7], 0, count, start, ret);
5920 
5921 exit:
5922 
5923     /* cleanup */
5924     wc_ecc_free(&userB);
5925     wc_ecc_free(&userA);
5926 }
5927 #endif
5928 #endif /* HAVE_ECC */
5929 
5930 #ifdef HAVE_CURVE25519
bench_curve25519KeyGen(void)5931 void bench_curve25519KeyGen(void)
5932 {
5933     curve25519_key genKey;
5934     double start;
5935     int    ret = 0, i, count;
5936     const char**desc = bench_desc_words[lng_index];
5937 
5938     /* Key Gen */
5939     bench_stats_start(&count, &start);
5940     do {
5941         for (i = 0; i < genTimes; i++) {
5942             ret = wc_curve25519_make_key(&gRng, 32, &genKey);
5943             wc_curve25519_free(&genKey);
5944             if (ret != 0) {
5945                 printf("wc_curve25519_make_key failed: %d\n", ret);
5946                 break;
5947             }
5948         }
5949         count += i;
5950     } while (bench_stats_sym_check(start));
5951     bench_stats_asym_finish("CURVE", 25519, desc[2], 0, count, start, ret);
5952 }
5953 
5954 #ifdef HAVE_CURVE25519_SHARED_SECRET
bench_curve25519KeyAgree(void)5955 void bench_curve25519KeyAgree(void)
5956 {
5957     curve25519_key genKey, genKey2;
5958     double start;
5959     int    ret, i, count;
5960     byte   shared[32];
5961     const char**desc = bench_desc_words[lng_index];
5962     word32 x = 0;
5963 
5964     wc_curve25519_init(&genKey);
5965     wc_curve25519_init(&genKey2);
5966 
5967     ret = wc_curve25519_make_key(&gRng, 32, &genKey);
5968     if (ret != 0) {
5969         printf("curve25519_make_key failed\n");
5970         return;
5971     }
5972     ret = wc_curve25519_make_key(&gRng, 32, &genKey2);
5973     if (ret != 0) {
5974         printf("curve25519_make_key failed: %d\n", ret);
5975         wc_curve25519_free(&genKey);
5976         return;
5977     }
5978 
5979     /* Shared secret */
5980     bench_stats_start(&count, &start);
5981     do {
5982         for (i = 0; i < agreeTimes; i++) {
5983             x = sizeof(shared);
5984             ret = wc_curve25519_shared_secret(&genKey, &genKey2, shared, &x);
5985             if (ret != 0) {
5986                 printf("curve25519_shared_secret failed: %d\n", ret);
5987                 goto exit;
5988             }
5989         }
5990         count += i;
5991     } while (bench_stats_sym_check(start));
5992 exit:
5993     bench_stats_asym_finish("CURVE", 25519, desc[3], 0, count, start, ret);
5994 
5995     wc_curve25519_free(&genKey2);
5996     wc_curve25519_free(&genKey);
5997 }
5998 #endif /* HAVE_CURVE25519_SHARED_SECRET */
5999 #endif /* HAVE_CURVE25519 */
6000 
6001 #ifdef HAVE_ED25519
bench_ed25519KeyGen(void)6002 void bench_ed25519KeyGen(void)
6003 {
6004     ed25519_key genKey;
6005     double start;
6006     int    i, count;
6007     const char**desc = bench_desc_words[lng_index];
6008 
6009     /* Key Gen */
6010     bench_stats_start(&count, &start);
6011     do {
6012         for (i = 0; i < genTimes; i++) {
6013             wc_ed25519_init(&genKey);
6014             (void)wc_ed25519_make_key(&gRng, 32, &genKey);
6015             wc_ed25519_free(&genKey);
6016         }
6017         count += i;
6018     } while (bench_stats_sym_check(start));
6019     bench_stats_asym_finish("ED", 25519, desc[2], 0, count, start, 0);
6020 }
6021 
6022 
bench_ed25519KeySign(void)6023 void bench_ed25519KeySign(void)
6024 {
6025     int    ret;
6026     ed25519_key genKey;
6027 #ifdef HAVE_ED25519_SIGN
6028     double start;
6029     int    i, count;
6030     byte   sig[ED25519_SIG_SIZE];
6031     byte   msg[512];
6032     word32 x = 0;
6033     const char**desc = bench_desc_words[lng_index];
6034 #endif
6035 
6036     wc_ed25519_init(&genKey);
6037 
6038     ret = wc_ed25519_make_key(&gRng, ED25519_KEY_SIZE, &genKey);
6039     if (ret != 0) {
6040         printf("ed25519_make_key failed\n");
6041         return;
6042     }
6043 
6044 #ifdef HAVE_ED25519_SIGN
6045     /* make dummy msg */
6046     for (i = 0; i < (int)sizeof(msg); i++)
6047         msg[i] = (byte)i;
6048 
6049     bench_stats_start(&count, &start);
6050     do {
6051         for (i = 0; i < agreeTimes; i++) {
6052             x = sizeof(sig);
6053             ret = wc_ed25519_sign_msg(msg, sizeof(msg), sig, &x, &genKey);
6054             if (ret != 0) {
6055                 printf("ed25519_sign_msg failed\n");
6056                 goto exit_ed_sign;
6057             }
6058         }
6059         count += i;
6060     } while (bench_stats_sym_check(start));
6061 exit_ed_sign:
6062     bench_stats_asym_finish("ED", 25519, desc[4], 0, count, start, ret);
6063 
6064 #ifdef HAVE_ED25519_VERIFY
6065     bench_stats_start(&count, &start);
6066     do {
6067         for (i = 0; i < agreeTimes; i++) {
6068             int verify = 0;
6069             ret = wc_ed25519_verify_msg(sig, x, msg, sizeof(msg), &verify,
6070                                         &genKey);
6071             if (ret != 0 || verify != 1) {
6072                 printf("ed25519_verify_msg failed\n");
6073                 goto exit_ed_verify;
6074             }
6075         }
6076         count += i;
6077     } while (bench_stats_sym_check(start));
6078 exit_ed_verify:
6079     bench_stats_asym_finish("ED", 25519, desc[5], 0, count, start, ret);
6080 #endif /* HAVE_ED25519_VERIFY */
6081 #endif /* HAVE_ED25519_SIGN */
6082 
6083     wc_ed25519_free(&genKey);
6084 }
6085 #endif /* HAVE_ED25519 */
6086 
6087 #ifdef HAVE_CURVE448
bench_curve448KeyGen(void)6088 void bench_curve448KeyGen(void)
6089 {
6090     curve448_key genKey;
6091     double start;
6092     int    ret = 0, i, count;
6093     const char**desc = bench_desc_words[lng_index];
6094 
6095     /* Key Gen */
6096     bench_stats_start(&count, &start);
6097     do {
6098         for (i = 0; i < genTimes; i++) {
6099             ret = wc_curve448_make_key(&gRng, 56, &genKey);
6100             wc_curve448_free(&genKey);
6101             if (ret != 0) {
6102                 printf("wc_curve448_make_key failed: %d\n", ret);
6103                 break;
6104             }
6105         }
6106         count += i;
6107     } while (bench_stats_sym_check(start));
6108     bench_stats_asym_finish("CURVE", 448, desc[2], 0, count, start, ret);
6109 }
6110 
6111 #ifdef HAVE_CURVE448_SHARED_SECRET
bench_curve448KeyAgree(void)6112 void bench_curve448KeyAgree(void)
6113 {
6114     curve448_key genKey, genKey2;
6115     double start;
6116     int    ret, i, count;
6117     byte   shared[56];
6118     const char**desc = bench_desc_words[lng_index];
6119     word32 x = 0;
6120 
6121     wc_curve448_init(&genKey);
6122     wc_curve448_init(&genKey2);
6123 
6124     ret = wc_curve448_make_key(&gRng, 56, &genKey);
6125     if (ret != 0) {
6126         printf("curve448_make_key failed\n");
6127         return;
6128     }
6129     ret = wc_curve448_make_key(&gRng, 56, &genKey2);
6130     if (ret != 0) {
6131         printf("curve448_make_key failed: %d\n", ret);
6132         wc_curve448_free(&genKey);
6133         return;
6134     }
6135 
6136     /* Shared secret */
6137     bench_stats_start(&count, &start);
6138     do {
6139         for (i = 0; i < agreeTimes; i++) {
6140             x = sizeof(shared);
6141             ret = wc_curve448_shared_secret(&genKey, &genKey2, shared, &x);
6142             if (ret != 0) {
6143                 printf("curve448_shared_secret failed: %d\n", ret);
6144                 goto exit;
6145             }
6146         }
6147         count += i;
6148     } while (bench_stats_sym_check(start));
6149 exit:
6150     bench_stats_asym_finish("CURVE", 448, desc[3], 0, count, start, ret);
6151 
6152     wc_curve448_free(&genKey2);
6153     wc_curve448_free(&genKey);
6154 }
6155 #endif /* HAVE_CURVE448_SHARED_SECRET */
6156 #endif /* HAVE_CURVE448 */
6157 
6158 #ifdef HAVE_ED448
bench_ed448KeyGen(void)6159 void bench_ed448KeyGen(void)
6160 {
6161     ed448_key genKey;
6162     double start;
6163     int    i, count;
6164     const char**desc = bench_desc_words[lng_index];
6165 
6166     /* Key Gen */
6167     bench_stats_start(&count, &start);
6168     do {
6169         for (i = 0; i < genTimes; i++) {
6170             wc_ed448_init(&genKey);
6171             (void)wc_ed448_make_key(&gRng, ED448_KEY_SIZE, &genKey);
6172             wc_ed448_free(&genKey);
6173         }
6174         count += i;
6175     } while (bench_stats_sym_check(start));
6176     bench_stats_asym_finish("ED", 448, desc[2], 0, count, start, 0);
6177 }
6178 
6179 
bench_ed448KeySign(void)6180 void bench_ed448KeySign(void)
6181 {
6182     int    ret;
6183     ed448_key genKey;
6184 #ifdef HAVE_ED448_SIGN
6185     double start;
6186     int    i, count;
6187     byte   sig[ED448_SIG_SIZE];
6188     byte   msg[512];
6189     word32 x = 0;
6190     const char**desc = bench_desc_words[lng_index];
6191 #endif
6192 
6193     wc_ed448_init(&genKey);
6194 
6195     ret = wc_ed448_make_key(&gRng, ED448_KEY_SIZE, &genKey);
6196     if (ret != 0) {
6197         printf("ed448_make_key failed\n");
6198         return;
6199     }
6200 
6201 #ifdef HAVE_ED448_SIGN
6202     /* make dummy msg */
6203     for (i = 0; i < (int)sizeof(msg); i++)
6204         msg[i] = (byte)i;
6205 
6206     bench_stats_start(&count, &start);
6207     do {
6208         for (i = 0; i < agreeTimes; i++) {
6209             x = sizeof(sig);
6210             ret = wc_ed448_sign_msg(msg, sizeof(msg), sig, &x, &genKey,
6211                                     NULL, 0);
6212             if (ret != 0) {
6213                 printf("ed448_sign_msg failed\n");
6214                 goto exit_ed_sign;
6215             }
6216         }
6217         count += i;
6218     } while (bench_stats_sym_check(start));
6219 exit_ed_sign:
6220     bench_stats_asym_finish("ED", 448, desc[4], 0, count, start, ret);
6221 
6222 #ifdef HAVE_ED448_VERIFY
6223     bench_stats_start(&count, &start);
6224     do {
6225         for (i = 0; i < agreeTimes; i++) {
6226             int verify = 0;
6227             ret = wc_ed448_verify_msg(sig, x, msg, sizeof(msg), &verify,
6228                                       &genKey, NULL, 0);
6229             if (ret != 0 || verify != 1) {
6230                 printf("ed448_verify_msg failed\n");
6231                 goto exit_ed_verify;
6232             }
6233         }
6234         count += i;
6235     } while (bench_stats_sym_check(start));
6236 exit_ed_verify:
6237     bench_stats_asym_finish("ED", 448, desc[5], 0, count, start, ret);
6238 #endif /* HAVE_ED448_VERIFY */
6239 #endif /* HAVE_ED448_SIGN */
6240 
6241     wc_ed448_free(&genKey);
6242 }
6243 #endif /* HAVE_ED448 */
6244 
6245 #ifdef WOLFCRYPT_HAVE_ECCSI
6246 #ifdef WOLFCRYPT_ECCSI_KMS
bench_eccsiKeyGen(void)6247 void bench_eccsiKeyGen(void)
6248 {
6249     EccsiKey genKey;
6250     double start;
6251     int    i, count;
6252     const char**desc = bench_desc_words[lng_index];
6253     int    ret;
6254 
6255     /* Key Gen */
6256     bench_stats_start(&count, &start);
6257     do {
6258         for (i = 0; i < genTimes; i++) {
6259             wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID);
6260             ret = wc_MakeEccsiKey(&genKey, &gRng);
6261             if (ret != 0) {
6262                 printf("wc_MakeEccsiKey failed: %d\n", ret);
6263                 break;
6264             }
6265             wc_FreeEccsiKey(&genKey);
6266         }
6267         count += i;
6268     } while (bench_stats_sym_check(start));
6269     bench_stats_asym_finish("ECCSI", 256, desc[2], 0, count, start, 0);
6270 }
6271 
bench_eccsiPairGen(void)6272 void bench_eccsiPairGen(void)
6273 {
6274     EccsiKey genKey;
6275     double start;
6276     int    i, count;
6277     const char**desc = bench_desc_words[lng_index];
6278     mp_int ssk;
6279     ecc_point* pvt;
6280     byte id[] = { 0x01, 0x23, 0x34, 0x45 };
6281     int ret;
6282 
6283     (void)mp_init(&ssk);
6284     pvt = wc_ecc_new_point();
6285     wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID);
6286     (void)wc_MakeEccsiKey(&genKey, &gRng);
6287 
6288     /* RSK Gen */
6289     bench_stats_start(&count, &start);
6290     do {
6291         for (i = 0; i < genTimes; i++) {
6292             ret = wc_MakeEccsiPair(&genKey, &gRng, WC_HASH_TYPE_SHA256, id,
6293                                    sizeof(id), &ssk, pvt);
6294             if (ret != 0) {
6295                 printf("wc_MakeEccsiPair failed: %d\n", ret);
6296                 break;
6297             }
6298         }
6299         count += i;
6300     } while (bench_stats_sym_check(start));
6301     bench_stats_asym_finish("ECCSI", 256, desc[12], 0, count, start, 0);
6302 
6303     wc_FreeEccsiKey(&genKey);
6304     wc_ecc_del_point(pvt);
6305     mp_free(&ssk);
6306 }
6307 #endif
6308 
6309 #ifdef WOLFCRYPT_ECCSI_CLIENT
bench_eccsiValidate(void)6310 void bench_eccsiValidate(void)
6311 {
6312     EccsiKey genKey;
6313     double start;
6314     int    i, count;
6315     const char**desc = bench_desc_words[lng_index];
6316     mp_int ssk;
6317     ecc_point* pvt;
6318     byte id[] = { 0x01, 0x23, 0x34, 0x45 };
6319     int valid;
6320     int ret;
6321 
6322     (void)mp_init(&ssk);
6323     pvt = wc_ecc_new_point();
6324     wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID);
6325     (void)wc_MakeEccsiKey(&genKey, &gRng);
6326     (void)wc_MakeEccsiPair(&genKey, &gRng, WC_HASH_TYPE_SHA256, id, sizeof(id),
6327                            &ssk, pvt);
6328 
6329     /* Validation of RSK */
6330     bench_stats_start(&count, &start);
6331     do {
6332         for (i = 0; i < genTimes; i++) {
6333             ret = wc_ValidateEccsiPair(&genKey, WC_HASH_TYPE_SHA256, id,
6334                                        sizeof(id), &ssk, pvt, &valid);
6335             if (ret != 0 || !valid) {
6336                 printf("wc_ValidateEccsiPair failed: %d (valid=%d))\n", ret,
6337                        valid);
6338                 break;
6339             }
6340         }
6341         count += i;
6342     } while (bench_stats_sym_check(start));
6343     bench_stats_asym_finish("ECCSI", 256, desc[11], 0, count, start, 0);
6344 
6345     wc_FreeEccsiKey(&genKey);
6346     wc_ecc_del_point(pvt);
6347     mp_free(&ssk);
6348 }
6349 
bench_eccsi(void)6350 void bench_eccsi(void)
6351 {
6352     EccsiKey genKey;
6353     double start;
6354     int    i, count;
6355     const char**desc = bench_desc_words[lng_index];
6356     mp_int ssk;
6357     ecc_point* pvt;
6358     byte id[] = { 0x01, 0x23, 0x34, 0x45 };
6359     byte msg[] = { 0x01, 0x23, 0x34, 0x45 };
6360     byte hash[WC_SHA256_DIGEST_SIZE];
6361     byte hashSz = (byte)sizeof(hash);
6362     byte sig[257];
6363     word32 sigSz = sizeof(sig);
6364     int ret;
6365     int verified;
6366 
6367     (void)mp_init(&ssk);
6368     pvt = wc_ecc_new_point();
6369     (void)wc_InitEccsiKey(&genKey, NULL, INVALID_DEVID);
6370     (void)wc_MakeEccsiKey(&genKey, &gRng);
6371     (void)wc_MakeEccsiPair(&genKey, &gRng, WC_HASH_TYPE_SHA256, id, sizeof(id),
6372                            &ssk, pvt);
6373     (void)wc_HashEccsiId(&genKey, WC_HASH_TYPE_SHA256, id, sizeof(id), pvt,
6374                          hash, &hashSz);
6375     (void)wc_SetEccsiHash(&genKey, hash, hashSz);
6376     (void)wc_SetEccsiPair(&genKey, &ssk, pvt);
6377 
6378     /* Encapsulate */
6379     bench_stats_start(&count, &start);
6380     do {
6381         for (i = 0; i < genTimes; i++) {
6382             ret = wc_SignEccsiHash(&genKey, &gRng, WC_HASH_TYPE_SHA256, msg,
6383                                    sizeof(msg), sig, &sigSz);
6384             if (ret != 0) {
6385                 printf("wc_SignEccsiHash failed: %d\n", ret);
6386                 break;
6387             }
6388         }
6389         count += i;
6390     } while (bench_stats_sym_check(start));
6391     bench_stats_asym_finish("ECCSI", 256, desc[4], 0, count, start, 0);
6392 
6393     /* Derive */
6394     bench_stats_start(&count, &start);
6395     do {
6396         for (i = 0; i < genTimes; i++) {
6397             ret = wc_VerifyEccsiHash(&genKey, WC_HASH_TYPE_SHA256, msg,
6398                                      sizeof(msg), sig, sigSz, &verified);
6399             if (ret != 0 || !verified) {
6400                 printf("wc_VerifyEccsiHash failed: %d (verified: %d)\n", ret,
6401                        verified);
6402                 break;
6403             }
6404         }
6405         count += i;
6406     } while (bench_stats_sym_check(start));
6407     bench_stats_asym_finish("ECCSI", 256, desc[5], 0, count, start, 0);
6408 
6409     wc_FreeEccsiKey(&genKey);
6410     wc_ecc_del_point(pvt);
6411 }
6412 #endif /* WOLFCRYPT_ECCSI_CLIENT */
6413 #endif /* WOLFCRYPT_HAVE_ECCSI */
6414 
6415 #ifdef WOLFCRYPT_HAVE_SAKKE
6416 #ifdef WOLFCRYPT_SAKKE_KMS
bench_sakkeKeyGen(void)6417 void bench_sakkeKeyGen(void)
6418 {
6419     SakkeKey genKey;
6420     double start;
6421     int    i, count;
6422     const char**desc = bench_desc_words[lng_index];
6423     int    ret;
6424 
6425     /* Key Gen */
6426     bench_stats_start(&count, &start);
6427     do {
6428         for (i = 0; i < genTimes; i++) {
6429             wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID);
6430             ret = wc_MakeSakkeKey(&genKey, &gRng);
6431             if (ret != 0) {
6432                 printf("wc_MakeSakkeKey failed: %d\n", ret);
6433                 break;
6434             }
6435             wc_FreeSakkeKey(&genKey);
6436         }
6437         count += i;
6438     } while (bench_stats_sym_check(start));
6439     bench_stats_asym_finish("SAKKE", 1024, desc[2], 0, count, start, 0);
6440 }
6441 
bench_sakkeRskGen(void)6442 void bench_sakkeRskGen(void)
6443 {
6444     SakkeKey genKey;
6445     double start;
6446     int    i, count;
6447     const char**desc = bench_desc_words[lng_index];
6448     ecc_point* rsk;
6449     byte id[] = { 0x01, 0x23, 0x34, 0x45 };
6450     int ret;
6451 
6452     rsk = wc_ecc_new_point();
6453     wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID);
6454     (void)wc_MakeSakkeKey(&genKey, &gRng);
6455 
6456     /* RSK Gen */
6457     bench_stats_start(&count, &start);
6458     do {
6459         for (i = 0; i < genTimes; i++) {
6460             ret = wc_MakeSakkeRsk(&genKey, id, sizeof(id), rsk);
6461             if (ret != 0) {
6462                 printf("wc_MakeSakkeRsk failed: %d\n", ret);
6463                 break;
6464             }
6465         }
6466         count += i;
6467     } while (bench_stats_sym_check(start));
6468     bench_stats_asym_finish("SAKKE", 1024, desc[8], 0, count, start, 0);
6469 
6470     wc_FreeSakkeKey(&genKey);
6471     wc_ecc_del_point(rsk);
6472 }
6473 #endif
6474 
6475 #ifdef WOLFCRYPT_SAKKE_CLIENT
bench_sakkeValidate(void)6476 void bench_sakkeValidate(void)
6477 {
6478     SakkeKey genKey;
6479     double start;
6480     int    i, count;
6481     const char**desc = bench_desc_words[lng_index];
6482     ecc_point* rsk;
6483     byte id[] = { 0x01, 0x23, 0x34, 0x45 };
6484     int valid;
6485     int ret;
6486 
6487     rsk = wc_ecc_new_point();
6488     (void)wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID);
6489     (void)wc_MakeSakkeKey(&genKey, &gRng);
6490     (void)wc_MakeSakkeRsk(&genKey, id, sizeof(id), rsk);
6491     (void)wc_ValidateSakkeRsk(&genKey, id, sizeof(id), rsk, &valid);
6492 
6493     /* Validation of RSK */
6494     bench_stats_start(&count, &start);
6495     do {
6496         for (i = 0; i < genTimes; i++) {
6497             ret = wc_ValidateSakkeRsk(&genKey, id, sizeof(id), rsk, &valid);
6498             if (ret != 0 || !valid) {
6499                 printf("wc_ValidateSakkeRsk failed: %d (valid=%d))\n", ret,
6500                        valid);
6501                 break;
6502             }
6503         }
6504         count += i;
6505     } while (bench_stats_sym_check(start));
6506     bench_stats_asym_finish("SAKKE", 1024, desc[11], 0, count, start, 0);
6507 
6508     wc_FreeSakkeKey(&genKey);
6509     wc_ecc_del_point(rsk);
6510 }
6511 
bench_sakke(void)6512 void bench_sakke(void)
6513 {
6514     SakkeKey genKey;
6515     double start;
6516     int    i, count;
6517     const char**desc = bench_desc_words[lng_index];
6518     ecc_point* rsk;
6519     byte id[] = { 0x01, 0x23, 0x34, 0x45 };
6520     byte ssv[] = { 0x01, 0x23, 0x34, 0x45 };
6521     byte derSSV[sizeof(ssv)];
6522     byte auth[257];
6523     word16 authSz = sizeof(auth);
6524     int ret = 0;
6525     byte* table = NULL;
6526     word32 len = 0;
6527     byte* iTable = NULL;
6528     word32 iTableLen = 0;
6529 
6530     rsk = wc_ecc_new_point();
6531     (void)wc_InitSakkeKey_ex(&genKey, 128, ECC_SAKKE_1, NULL, INVALID_DEVID);
6532     (void)wc_MakeSakkeKey(&genKey, &gRng);
6533     (void)wc_MakeSakkeRsk(&genKey, id, sizeof(id), rsk);
6534     (void)wc_SetSakkeRsk(&genKey, rsk, NULL, 0);
6535     (void)wc_SetSakkeIdentity(&genKey, id, sizeof(id));
6536 
6537     /* Encapsulate */
6538     bench_stats_start(&count, &start);
6539     do {
6540         for (i = 0; i < genTimes; i++) {
6541             ret = wc_MakeSakkeEncapsulatedSSV(&genKey, WC_HASH_TYPE_SHA256, ssv,
6542                                               sizeof(ssv), auth, &authSz);
6543             if (ret != 0) {
6544                 printf("wc_MakeSakkeEncapsulatedSSV failed: %d\n", ret);
6545                 break;
6546             }
6547         }
6548         count += i;
6549     } while (bench_stats_sym_check(start));
6550     bench_stats_asym_finish("SAKKE", 1024, desc[9], 0, count, start, 0);
6551 
6552     /* Derive */
6553     bench_stats_start(&count, &start);
6554     do {
6555         for (i = 0; i < genTimes; i++) {
6556             XMEMCPY(derSSV, ssv, sizeof(ssv));
6557             ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV,
6558                                     sizeof(derSSV), auth, authSz);
6559             if (ret != 0) {
6560                 printf("wc_DeriveSakkeSSV failed: %d\n", ret);
6561                 break;
6562             }
6563         }
6564         if (ret != 0) break;
6565         count += i;
6566     } while (bench_stats_sym_check(start));
6567     bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0);
6568 
6569     /* Calculate Point I and generate table. */
6570     (void)wc_MakeSakkePointI(&genKey, id, sizeof(id));
6571     iTableLen = 0;
6572     (void)wc_GenerateSakkePointITable(&genKey, NULL, &iTableLen);
6573     if (iTableLen != 0) {
6574         iTable = (byte*)XMALLOC(iTableLen, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6575         (void)wc_GenerateSakkePointITable(&genKey, iTable, &iTableLen);
6576     }
6577 
6578     /* Encapsulate with Point I table */
6579     bench_stats_start(&count, &start);
6580     do {
6581         for (i = 0; i < genTimes; i++) {
6582             ret = wc_MakeSakkeEncapsulatedSSV(&genKey, WC_HASH_TYPE_SHA256, ssv,
6583                 sizeof(ssv), auth, &authSz);
6584             if (ret != 0) {
6585                 printf("wc_MakeSakkeEncapsulatedSSV failed: %d\n", ret);
6586                 break;
6587             }
6588         }
6589         count += i;
6590     } while (bench_stats_sym_check(start));
6591     bench_stats_asym_finish("SAKKE", 1024, desc[9], 0, count, start, 0);
6592 
6593     (void)wc_SetSakkeRsk(&genKey, rsk, table, len);
6594 
6595     /* Derive with Point I table */
6596     bench_stats_start(&count, &start);
6597     do {
6598         for (i = 0; i < genTimes; i++) {
6599             XMEMCPY(derSSV, ssv, sizeof(ssv));
6600             ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV,
6601                                     sizeof(derSSV), auth, authSz);
6602             if (ret != 0) {
6603                 printf("wc_DeriveSakkeSSV failed: %d\n", ret);
6604                 break;
6605             }
6606         }
6607         if (ret != 0) break;
6608         count += i;
6609     } while (bench_stats_sym_check(start));
6610     bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0);
6611 
6612     len = 0;
6613     (void)wc_GenerateSakkeRskTable(&genKey, rsk, NULL, &len);
6614     if (len > 0) {
6615         table = (byte*)XMALLOC(len, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6616         (void)wc_GenerateSakkeRskTable(&genKey, rsk, table, &len);
6617     }
6618     (void)wc_SetSakkeRsk(&genKey, rsk, table, len);
6619 
6620     /* Derive with Point I table and RSK table */
6621     bench_stats_start(&count, &start);
6622     do {
6623         for (i = 0; i < genTimes; i++) {
6624             XMEMCPY(derSSV, ssv, sizeof(ssv));
6625             ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV,
6626                                     sizeof(derSSV), auth, authSz);
6627             if (ret != 0) {
6628                 printf("wc_DeriveSakkeSSV failed: %d\n", ret);
6629                 break;
6630             }
6631         }
6632         if (ret != 0) break;
6633         count += i;
6634     } while (bench_stats_sym_check(start));
6635     bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0);
6636 
6637     wc_ClearSakkePointITable(&genKey);
6638     /* Derive with RSK table */
6639     bench_stats_start(&count, &start);
6640     do {
6641         for (i = 0; i < genTimes; i++) {
6642             XMEMCPY(derSSV, ssv, sizeof(ssv));
6643             ret = wc_DeriveSakkeSSV(&genKey, WC_HASH_TYPE_SHA256, derSSV,
6644                                     sizeof(derSSV), auth, authSz);
6645             if (ret != 0) {
6646                 printf("wc_DeriveSakkeSSV failed: %d\n", ret);
6647                 break;
6648             }
6649         }
6650         if (ret != 0) break;
6651         count += i;
6652     } while (bench_stats_sym_check(start));
6653     bench_stats_asym_finish("SAKKE", 1024, desc[10], 0, count, start, 0);
6654 
6655     wc_FreeSakkeKey(&genKey);
6656     wc_ecc_del_point(rsk);
6657 }
6658 #endif /* WOLFCRYPT_SAKKE_CLIENT */
6659 #endif /* WOLFCRYPT_HAVE_SAKKE */
6660 
6661 #ifdef HAVE_PQC
bench_pqcKemInit(word32 alg,byte ** priv_key,byte ** pub_key,const char ** wolf_name,OQS_KEM ** kem)6662 static void bench_pqcKemInit(word32 alg, byte **priv_key, byte **pub_key,
6663                    const char **wolf_name, OQS_KEM **kem)
6664 {
6665     int i;
6666     const char *pqc_name = NULL;
6667 
6668     *pub_key = NULL;
6669     *priv_key = NULL;
6670 
6671     for (i=0; bench_pq_asym_opt[i].str != NULL; i++) {
6672         if (alg ==  bench_pq_asym_opt[i].val) {
6673             pqc_name = bench_pq_asym_opt[i].pqc_name;
6674             *wolf_name = bench_pq_asym_opt[i].str;
6675             break;
6676         }
6677     }
6678 
6679     if (pqc_name == NULL) {
6680         printf("Bad OQS Alg specified\n");
6681         return;
6682     }
6683 
6684 #ifdef HAVE_LIBOQS
6685     *kem = OQS_KEM_new(pqc_name);
6686     if (*kem == NULL) {
6687         printf("OQS_KEM_new() failed\n");
6688         return;
6689     }
6690 #endif
6691 
6692     *pub_key = (byte*)XMALLOC((*kem)->length_public_key, HEAP_HINT,
6693                               DYNAMIC_TYPE_TMP_BUFFER);
6694 
6695 
6696     *priv_key = (byte*)XMALLOC((*kem)->length_secret_key, HEAP_HINT,
6697                                DYNAMIC_TYPE_TMP_BUFFER);
6698 
6699 }
6700 
bench_pqcKemKeygen(word32 alg)6701 void bench_pqcKemKeygen(word32 alg)
6702 {
6703     const char *wolf_name = NULL;
6704     OQS_KEM* kem = NULL;
6705     double start;
6706     int i, count, ret;
6707     byte *priv_key;
6708     byte *pub_key;
6709 
6710     bench_pqcKemInit(alg, &priv_key, &pub_key, &wolf_name, &kem);
6711 
6712     if (wolf_name == NULL || kem == NULL || pub_key == NULL ||
6713         priv_key == NULL) {
6714         printf("bench_pqcKemInit() failed\n");
6715         goto exit;
6716     }
6717 
6718     bench_stats_start(&count, &start);
6719     do {
6720         for (i = 0; i < genTimes; i++) {
6721 #ifdef HAVE_LIBOQS
6722             ret = OQS_KEM_keypair(kem, pub_key, priv_key);
6723             if (ret != OQS_SUCCESS) {
6724                 printf("OQS_KEM_keypair() failed: %d\n", ret);
6725                 goto exit;
6726             }
6727 #endif
6728         }
6729         count += i;
6730     } while (bench_stats_sym_check(start));
6731 
6732     /* + 1 gets rid of the leading dash (-) */
6733     bench_stats_pq_asym_finish(wolf_name + 1, 0, count, start, 0);
6734 
6735 exit:
6736     XFREE(priv_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6737     XFREE(pub_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6738     OQS_KEM_free(kem);
6739 
6740 }
6741 
bench_pqcKemEncapDecap(word32 alg)6742 void bench_pqcKemEncapDecap(word32 alg)
6743 {
6744     const char *wolf_name = NULL;
6745     OQS_KEM* kem = NULL;
6746     double start;
6747     int i, count, ret;
6748     byte *priv_key;
6749     byte *pub_key;
6750     byte *ciphertext = NULL;
6751     byte *shared_secret = NULL;
6752 
6753     bench_pqcKemInit(alg, &priv_key, &pub_key, &wolf_name, &kem);
6754 
6755     if (wolf_name == NULL || kem == NULL || pub_key == NULL ||
6756         priv_key == NULL) {
6757         printf("bench_pqcKemInit() failed\n");
6758         goto exit;
6759     }
6760 
6761 #ifdef HAVE_LIBOQS
6762     ret = OQS_KEM_keypair(kem, pub_key, priv_key);
6763     if (ret != OQS_SUCCESS) {
6764         printf("OQS_KEM_keypair() failed: %d\n", ret);
6765         goto exit;
6766     }
6767 #endif
6768 
6769     shared_secret = (byte*)XMALLOC(kem->length_shared_secret, HEAP_HINT,
6770                                    DYNAMIC_TYPE_TMP_BUFFER);
6771 
6772     ciphertext = (byte*)XMALLOC(kem->length_ciphertext, HEAP_HINT,
6773                                    DYNAMIC_TYPE_TMP_BUFFER);
6774 
6775     if (shared_secret == NULL || ciphertext == NULL) {
6776         printf("XMALLOC() failed\n");
6777         goto exit;
6778     }
6779 
6780     if (ret == OQS_SUCCESS) {
6781         bench_stats_start(&count, &start);
6782         do {
6783             for (i = 0; i < agreeTimes; i++) {
6784 #ifdef HAVE_LIBOQS
6785                 ret = OQS_KEM_encaps(kem, ciphertext, shared_secret, pub_key);
6786                 if (ret != OQS_SUCCESS) {
6787                     printf("OQS_KEM_encaps() failed: %d\n", ret);
6788                     goto exit;
6789                 }
6790 
6791                 ret = OQS_KEM_decaps(kem, shared_secret, ciphertext, priv_key);
6792                 if (ret != OQS_SUCCESS) {
6793                     printf("OQS_KEM_decaps() failed: %d\n", ret);
6794                     goto exit;
6795                 }
6796 #endif
6797             }
6798             count += i;
6799         } while (bench_stats_sym_check(start));
6800 
6801         /* + 1 gets rid of the leading dash (-) */
6802         bench_stats_pq_asym_finish(wolf_name + 1, 0, count, start, ret);
6803     }
6804 
6805 exit:
6806     XFREE(ciphertext, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6807     XFREE(shared_secret, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6808     XFREE(priv_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6809     XFREE(pub_key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
6810     OQS_KEM_free(kem);
6811 }
6812 
bench_falconKeySign(byte level)6813 void bench_falconKeySign(byte level)
6814 {
6815     int    ret = 0;
6816     falcon_key key;
6817     double start;
6818     int    i, count;
6819     byte   sig[FALCON_MAX_SIG_SIZE];
6820     byte   msg[512];
6821     word32 x = 0;
6822     const char**desc = bench_desc_words[lng_index];
6823 
6824     ret = wc_falcon_init(&key);
6825     if (ret != 0) {
6826         printf("wc_falcon_init failed %d\n", ret);
6827         return;
6828     }
6829 
6830     ret = wc_falcon_set_level(&key, level);
6831     if (ret != 0) {
6832         printf("wc_falcon_set_level failed %d\n", ret);
6833     }
6834 
6835     if (ret == 0) {
6836         if (level == 1) {
6837             ret = wc_falcon_import_private_key(bench_falcon_level1_key,
6838                                                sizeof_bench_falcon_level1_key,
6839                                                NULL, 0, &key);
6840         }
6841         else {
6842             ret = wc_falcon_import_private_key(bench_falcon_level5_key,
6843                                                sizeof_bench_falcon_level5_key,
6844                                                NULL, 0, &key);
6845         }
6846 
6847         if (ret != 0) {
6848             printf("wc_falcon_import_private_key failed %d\n", ret);
6849         }
6850     }
6851 
6852     /* make dummy msg */
6853     for (i = 0; i < (int)sizeof(msg); i++) {
6854         msg[i] = (byte)i;
6855     }
6856 
6857     bench_stats_start(&count, &start);
6858     do {
6859         for (i = 0; i < agreeTimes; i++) {
6860             if (ret == 0) {
6861                 if (level == 1) {
6862                     x = FALCON_LEVEL1_SIG_SIZE;
6863                     ret = wc_falcon_sign_msg(msg, sizeof(msg), sig, &x, &key);
6864                 }
6865                 else {
6866                     x = FALCON_LEVEL5_SIG_SIZE;
6867                     ret = wc_falcon_sign_msg(msg, sizeof(msg), sig, &x, &key);
6868                 }
6869                 if (ret != 0) {
6870                     printf("wc_falcon_sign_msg failed\n");
6871                 }
6872             }
6873         }
6874         count += i;
6875     } while (bench_stats_sym_check(start));
6876 
6877     if (ret == 0) {
6878         bench_stats_asym_finish("FALCON", level, desc[4], 0, count, start, ret);
6879     }
6880 
6881     bench_stats_start(&count, &start);
6882     do {
6883         for (i = 0; i < agreeTimes; i++) {
6884             if (ret == 0) {
6885                 int verify = 0;
6886                 if (level == 1) {
6887                     ret = wc_falcon_verify_msg(sig, x, msg, sizeof(msg),
6888                                                &verify, &key);
6889                 }
6890                 else {
6891                     ret = wc_falcon_verify_msg(sig, x, msg, sizeof(msg),
6892                                                &verify, &key);
6893                 }
6894 
6895                 if (ret != 0 || verify != 1) {
6896                     printf("wc_falcon_verify_msg failed %d, verify %d\n",
6897                         ret, verify);
6898                     ret = -1;
6899                 }
6900             }
6901         }
6902         count += i;
6903     } while (bench_stats_sym_check(start));
6904 
6905     if (ret == 0) {
6906         bench_stats_asym_finish("FALCON", level, desc[5], 0, count, start, ret);
6907     }
6908 
6909     wc_falcon_free(&key);
6910 }
6911 #endif /* HAVE_PQC */
6912 
6913 #ifndef HAVE_STACK_SIZE
6914 #if defined(_WIN32) && !defined(INTIME_RTOS)
6915 
6916     #define WIN32_LEAN_AND_MEAN
6917     #include <windows.h>
6918 
current_time(int reset)6919     double current_time(int reset)
6920     {
6921         static int init = 0;
6922         static LARGE_INTEGER freq;
6923 
6924         LARGE_INTEGER count;
6925 
6926         (void)reset;
6927 
6928         if (!init) {
6929             QueryPerformanceFrequency(&freq);
6930             init = 1;
6931         }
6932 
6933         QueryPerformanceCounter(&count);
6934 
6935         return (double)count.QuadPart / freq.QuadPart;
6936     }
6937 
6938 #elif defined MICROCHIP_PIC32
6939     #if defined(WOLFSSL_MICROCHIP_PIC32MZ)
6940         #define CLOCK 80000000.0
6941     #else
6942         #define CLOCK 40000000.0
6943     #endif
6944     extern void WriteCoreTimer(word32 t);
6945     extern word32 ReadCoreTimer(void);
current_time(int reset)6946     double current_time(int reset)
6947     {
6948         unsigned int ns;
6949 
6950         if (reset) {
6951             WriteCoreTimer(0);
6952         }
6953 
6954         /* get timer in ns */
6955         ns = ReadCoreTimer();
6956 
6957         /* return seconds as a double */
6958         return ( ns / CLOCK * 2.0);
6959     }
6960 
6961 #elif defined(WOLFSSL_IAR_ARM_TIME) || defined (WOLFSSL_MDK_ARM) || \
6962       defined(WOLFSSL_USER_CURRTIME) || defined(WOLFSSL_CURRTIME_REMAP)
6963     /* declared above at line 239 */
6964     /* extern   double current_time(int reset); */
6965 
6966 #elif defined(FREERTOS)
6967 
6968     #include "task.h"
6969 #if defined(WOLFSSL_ESPIDF)
6970     /* proto type definition */
6971     int construct_argv();
6972     extern char* __argv[22];
6973 #endif
current_time(int reset)6974     double current_time(int reset)
6975     {
6976         portTickType tickCount;
6977 
6978         (void) reset;
6979 
6980         /* tick count == ms, if configTICK_RATE_HZ is set to 1000 */
6981         tickCount = xTaskGetTickCount();
6982         return (double)tickCount / 1000;
6983     }
6984 
6985 #elif defined (WOLFSSL_TIRTOS)
6986 
6987     extern double current_time(int reset);
6988 
6989 #elif defined(FREESCALE_MQX)
6990 
current_time(int reset)6991     double current_time(int reset)
6992     {
6993         TIME_STRUCT tv;
6994         _time_get(&tv);
6995 
6996         return (double)tv.SECONDS + (double)tv.MILLISECONDS / 1000;
6997     }
6998 
6999 #elif defined(FREESCALE_KSDK_BM)
7000 
current_time(int reset)7001     double current_time(int reset)
7002     {
7003         return (double)OSA_TimeGetMsec() / 1000;
7004     }
7005 
7006 #elif defined(WOLFSSL_EMBOS)
7007 
7008     #include "RTOS.h"
7009 
current_time(int reset)7010     double current_time(int reset)
7011     {
7012         double time_now;
7013         double current_s = OS_GetTime() / 1000.0;
7014         double current_us = OS_GetTime_us() / 1000000.0;
7015         time_now = (double)( current_s + current_us);
7016 
7017         (void) reset;
7018 
7019         return time_now;
7020     }
7021 #elif defined(WOLFSSL_SGX)
7022     double current_time(int reset);
7023 
7024 #elif defined(WOLFSSL_DEOS)
current_time(int reset)7025     double current_time(int reset)
7026     {
7027         const uint32_t systemTickTimeInHz = 1000000 / systemTickInMicroseconds();
7028         const volatile uint32_t *systemTickPtr = systemTickPointer();
7029 
7030         (void)reset;
7031 
7032         return (double) *systemTickPtr/systemTickTimeInHz;
7033     }
7034 
7035 #elif defined(MICRIUM)
current_time(int reset)7036     double current_time(int reset)
7037     {
7038 
7039 #if (OS_VERSION < 50000)
7040         CPU_ERR err;
7041         (void)reset;
7042         return (double) CPU_TS_Get32()/CPU_TS_TmrFreqGet(&err);
7043 #else
7044         RTOS_ERR  err;
7045         double ret = 0;
7046         OS_TICK tick = OSTimeGet(&err);
7047         OS_RATE_HZ rate = OSTimeTickRateHzGet(&err);
7048         (void)reset;
7049 
7050         if (RTOS_ERR_CODE_GET(err) == RTOS_ERR_NONE) {
7051             ret = ((double)tick)/rate;
7052         }
7053         return ret;
7054 #endif
7055     }
7056 #elif defined(WOLFSSL_ZEPHYR)
7057 
7058     #include <time.h>
7059 
current_time(int reset)7060     double current_time(int reset)
7061     {
7062         (void)reset;
7063 
7064      #if defined(CONFIG_ARCH_POSIX)
7065          k_cpu_idle();
7066      #endif
7067 
7068         return (double)k_uptime_get() / 1000;
7069     }
7070 
7071 #elif defined(WOLFSSL_NETBURNER)
7072     #include <predef.h>
7073     #include <utils.h>
7074     #include <constants.h>
7075 
current_time(int reset)7076     double current_time(int reset)
7077     {
7078         DWORD ticks = TimeTick; /* ticks since system start */
7079         (void)reset;
7080 
7081         return (double) ticks/TICKS_PER_SECOND;
7082     }
7083 
7084 #elif defined(THREADX)
7085     #include "tx_api.h"
current_time(int reset)7086     double current_time(int reset)
7087     {
7088         (void)reset;
7089         return (double) tx_time_get() / TX_TIMER_TICKS_PER_SECOND;
7090     }
7091 
7092 #elif defined(WOLFSSL_XILINX)
7093     #ifndef XPAR_CPU_CORTEXA53_0_TIMESTAMP_CLK_FREQ
7094     #define XPAR_CPU_CORTEXA53_0_TIMESTAMP_CLK_FREQ 50000000
7095     #endif
7096     #ifndef COUNTS_PER_SECOND
7097     #define COUNTS_PER_SECOND     XPAR_CPU_CORTEXA53_0_TIMESTAMP_CLK_FREQ
7098     #endif
7099 
current_time(int reset)7100     double current_time(int reset)
7101     {
7102         double timer;
7103         uint64_t cntPct = 0;
7104         asm volatile("mrs %0, CNTPCT_EL0" : "=r" (cntPct));
7105 
7106         /* Convert to milliseconds */
7107         timer = (double)(cntPct / (COUNTS_PER_SECOND / 1000));
7108         /* Convert to seconds.millisecond */
7109         timer /= 1000;
7110         return timer;
7111     }
7112 
7113 #else
7114 
7115     #include <sys/time.h>
7116 
current_time(int reset)7117     double current_time(int reset)
7118     {
7119         struct timeval tv;
7120 
7121         (void)reset;
7122 
7123         gettimeofday(&tv, 0);
7124 
7125         return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
7126     }
7127 
7128 #endif /* _WIN32 */
7129 #endif /* !HAVE_STACK_SIZE */
7130 
7131 #if defined(HAVE_GET_CYCLES)
7132 
get_intel_cycles(void)7133 static WC_INLINE word64 get_intel_cycles(void)
7134 {
7135     unsigned int lo_c, hi_c;
7136     __asm__ __volatile__ (
7137         "cpuid\n\t"
7138         "rdtsc"
7139             : "=a"(lo_c), "=d"(hi_c)   /* out */
7140             : "a"(0)                   /* in */
7141             : "%ebx", "%ecx");         /* clobber */
7142     return ((word64)lo_c) | (((word64)hi_c) << 32);
7143 }
7144 
7145 #endif /* HAVE_GET_CYCLES */
7146 
benchmark_configure(int block_size)7147 void benchmark_configure(int block_size)
7148 {
7149     /* must be greater than 0 */
7150     if (block_size > 0) {
7151         numBlocks = numBlocks * bench_size / block_size;
7152         bench_size = (word32)block_size;
7153     }
7154 }
7155 
7156 #ifndef NO_MAIN_DRIVER
7157 
7158 #ifndef MAIN_NO_ARGS
7159 
7160 #ifndef WOLFSSL_BENCHMARK_ALL
7161 /* Display the algorithm string and keep to 80 characters per line.
7162  *
7163  * str   Algorithm string to print.
7164  * line  Length of line used so far.
7165  */
print_alg(const char * str,int * line)7166 static void print_alg(const char* str, int* line)
7167 {
7168     int optLen;
7169 
7170     optLen = (int)XSTRLEN(str) + 1;
7171     if (optLen + *line > 80) {
7172         printf("\n             ");
7173         *line = 13;
7174     }
7175     *line += optLen;
7176     printf(" %s", str);
7177 }
7178 #endif
7179 
7180 /* Display the usage options of the benchmark program. */
Usage(void)7181 static void Usage(void)
7182 {
7183 #ifndef WOLFSSL_BENCHMARK_ALL
7184     int i;
7185     int line;
7186 #endif
7187 
7188     printf("benchmark\n");
7189     printf("%s", bench_Usage_msg1[lng_index][0]);    /* option -? */
7190     printf("%s", bench_Usage_msg1[lng_index][1]);    /* option -csv */
7191     printf("%s", bench_Usage_msg1[lng_index][2]);    /* option -base10 */
7192 #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
7193     printf("%s", bench_Usage_msg1[lng_index][3]);    /* option -no_add */
7194 #endif
7195     printf("%s", bench_Usage_msg1[lng_index][4]);    /* option -dgst_full */
7196 #ifndef NO_RSA
7197     printf("%s", bench_Usage_msg1[lng_index][5]);    /* option -ras_sign */
7198     #ifdef WOLFSSL_KEY_GEN
7199     printf("%s", bench_Usage_msg1[lng_index][6]);    /* option -rsa-sz */
7200     #endif
7201 #endif
7202 #if !defined(NO_DH) && defined(HAVE_FFDHE_2048)
7203     printf("%s", bench_Usage_msg1[lng_index][7]);    /* option -ffdhe2048 */
7204 #endif
7205 #if !defined(NO_DH) && defined(HAVE_FFDHE_3072)
7206     printf("%s", bench_Usage_msg1[lng_index][8]);    /* option -ffdhe3072 */
7207 #endif
7208 #if defined(HAVE_ECC) && !defined(NO_ECC256)
7209     printf("%s", bench_Usage_msg1[lng_index][9]);    /* option -p256 */
7210 #endif
7211 #if defined(HAVE_ECC) && defined(HAVE_ECC384)
7212     printf("%s", bench_Usage_msg1[lng_index][10]);   /* option -p384 */
7213 #endif
7214 #if defined(HAVE_ECC)
7215     printf("%s", bench_Usage_msg1[lng_index][11]);   /* option -ecc-all */
7216 #endif
7217 #ifndef WOLFSSL_BENCHMARK_ALL
7218     printf("%s", bench_Usage_msg1[lng_index][12]);   /* option -<alg> */
7219     printf("             ");
7220     line = 13;
7221     for (i=0; bench_cipher_opt[i].str != NULL; i++)
7222         print_alg(bench_cipher_opt[i].str + 1, &line);
7223     printf("\n             ");
7224     line = 13;
7225     for (i=0; bench_digest_opt[i].str != NULL; i++)
7226         print_alg(bench_digest_opt[i].str + 1, &line);
7227     printf("\n             ");
7228     line = 13;
7229     for (i=0; bench_mac_opt[i].str != NULL; i++)
7230         print_alg(bench_mac_opt[i].str + 1, &line);
7231     printf("\n             ");
7232     line = 13;
7233     for (i=0; bench_asym_opt[i].str != NULL; i++)
7234         print_alg(bench_asym_opt[i].str + 1, &line);
7235     printf("\n             ");
7236     line = 13;
7237     for (i=0; bench_other_opt[i].str != NULL; i++)
7238         print_alg(bench_other_opt[i].str + 1, &line);
7239     printf("\n");
7240 #endif
7241     printf("%s", bench_Usage_msg1[lng_index][13]);   /* option -lng */
7242     printf("%s", bench_Usage_msg1[lng_index][14]);   /* option <num> */
7243 #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING)
7244     printf("%s", bench_Usage_msg1[lng_index][15]);   /* option -threads <num> */
7245 #endif
7246     printf("%s", bench_Usage_msg1[lng_index][16]);   /* option -print */
7247 }
7248 
7249 /* Match the command line argument with the string.
7250  *
7251  * arg  Command line argument.
7252  * str  String to check for.
7253  * return 1 if the command line argument matches the string, 0 otherwise.
7254  */
string_matches(const char * arg,const char * str)7255 static int string_matches(const char* arg, const char* str)
7256 {
7257     int len = (int)XSTRLEN(str) + 1;
7258     return XSTRNCMP(arg, str, len) == 0;
7259 }
7260 #endif /* MAIN_NO_ARGS */
7261 
7262 #if defined(WOLFSSL_ESPIDF) || defined(_WIN32_WCE)
wolf_benchmark_task()7263 int wolf_benchmark_task( )
7264 #elif defined(MAIN_NO_ARGS)
7265 int main()
7266 #else
7267 int main(int argc, char** argv)
7268 #endif
7269 {
7270     int ret = 0;
7271 #ifndef MAIN_NO_ARGS
7272     int optMatched;
7273 #ifdef WOLFSSL_ESPIDF
7274     int argc = construct_argv();
7275     char** argv = (char**)__argv;
7276 #endif
7277 #ifndef WOLFSSL_BENCHMARK_ALL
7278     int i;
7279 #endif
7280 #endif
7281 
7282     benchmark_static_init();
7283 
7284 #ifndef MAIN_NO_ARGS
7285     while (argc > 1) {
7286         if (string_matches(argv[1], "-?")) {
7287             if(--argc>1){
7288                 lng_index = XATOI((++argv)[1]);
7289                 if(lng_index<0||lng_index>1) {
7290                     lng_index = 0;
7291                 }
7292             }
7293             Usage();
7294             return 0;
7295         }
7296         else if (string_matches(argv[1], "-v")) {
7297             printf("-----------------------------------------------------------"
7298                    "-------------------\n wolfSSL version %s\n-----------------"
7299                    "-----------------------------------------------------------"
7300                    "--\n", LIBWOLFSSL_VERSION_STRING);
7301             return 0;
7302         }
7303         else if (string_matches(argv[1], "-lng")) {
7304             argc--;
7305             argv++;
7306             if(argc>1) {
7307                 lng_index = XATOI(argv[1]);
7308                 if(lng_index<0||lng_index>1){
7309                     printf("invalid number(%d) is specified. [<num> :0-1]\n",lng_index);
7310                     lng_index = 0;
7311                 }
7312             }
7313         }
7314         else if (string_matches(argv[1], "-base10"))
7315             base2 = 0;
7316 #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
7317         else if (string_matches(argv[1], "-no_aad"))
7318             aesAuthAddSz = 0;
7319 #endif
7320         else if (string_matches(argv[1], "-dgst_full"))
7321             digest_stream = 0;
7322 #ifndef NO_RSA
7323         else if (string_matches(argv[1], "-rsa_sign"))
7324             rsa_sign_verify = 1;
7325 #endif
7326 #if !defined(NO_DH) && defined(HAVE_FFDHE_2048)
7327         else if (string_matches(argv[1], "-ffdhe2048"))
7328             use_ffdhe = 2048;
7329 #endif
7330 #if !defined(NO_DH) && defined(HAVE_FFDHE_3072)
7331         else if (string_matches(argv[1], "-ffdhe3072"))
7332             use_ffdhe = 3072;
7333 #endif
7334 #if !defined(NO_DH) && defined(HAVE_FFDHE_4096)
7335         else if (string_matches(argv[1], "-ffdhe4096"))
7336             use_ffdhe = 4096;
7337 #endif
7338 #if defined(HAVE_ECC) && !defined(NO_ECC256)
7339         else if (string_matches(argv[1], "-p256"))
7340             bench_asym_algs |= BENCH_ECC_P256;
7341 #endif
7342 #if defined(HAVE_ECC) && defined(HAVE_ECC384)
7343         else if (string_matches(argv[1], "-p384"))
7344             bench_asym_algs |= BENCH_ECC_P384;
7345 #endif
7346 #ifdef BENCH_ASYM
7347         else if (string_matches(argv[1], "-csv")) {
7348             csv_format = 1;
7349             csv_header_count = 1;
7350         }
7351 #endif
7352 #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING)
7353         else if (string_matches(argv[1], "-threads")) {
7354             argc--;
7355             argv++;
7356             if (argc > 1) {
7357                 g_threadCount = XATOI(argv[1]);
7358                 if (g_threadCount < 1 || lng_index > 128){
7359                     printf("invalid number(%d) is specified. [<num> :1-128]\n",
7360                         g_threadCount);
7361                     g_threadCount = 0;
7362                 }
7363             }
7364         }
7365 #endif
7366         else if (string_matches(argv[1], "-print")) {
7367             gPrintStats = 1;
7368         }
7369         else if (argv[1][0] == '-') {
7370             optMatched = 0;
7371 #ifndef WOLFSSL_BENCHMARK_ALL
7372             /* Check known algorithm choosing command line options. */
7373             /* Known cipher algorithms */
7374             for (i=0; !optMatched && bench_cipher_opt[i].str != NULL; i++) {
7375                 if (string_matches(argv[1], bench_cipher_opt[i].str)) {
7376                     bench_cipher_algs |= bench_cipher_opt[i].val;
7377                     bench_all = 0;
7378                     optMatched = 1;
7379                 }
7380             }
7381             /* Known digest algorithms */
7382             for (i=0; !optMatched && bench_digest_opt[i].str != NULL; i++) {
7383                 if (string_matches(argv[1], bench_digest_opt[i].str)) {
7384                     bench_digest_algs |= bench_digest_opt[i].val;
7385                     bench_all = 0;
7386                     optMatched = 1;
7387                 }
7388             }
7389             /* Known MAC algorithms */
7390             for (i=0; !optMatched && bench_mac_opt[i].str != NULL; i++) {
7391                 if (string_matches(argv[1], bench_mac_opt[i].str)) {
7392                     bench_mac_algs |= bench_mac_opt[i].val;
7393                     bench_all = 0;
7394                     optMatched = 1;
7395                 }
7396             }
7397             /* Known asymmetric algorithms */
7398             for (i=0; !optMatched && bench_asym_opt[i].str != NULL; i++) {
7399                 if (string_matches(argv[1], bench_asym_opt[i].str)) {
7400                     bench_asym_algs |= bench_asym_opt[i].val;
7401                     bench_all = 0;
7402                     optMatched = 1;
7403                 }
7404             }
7405             /* Known asymmetric post-quantum algorithms */
7406             for (i=0; !optMatched && bench_pq_asym_opt[i].str != NULL; i++) {
7407                 if (string_matches(argv[1], bench_pq_asym_opt[i].str)) {
7408                     bench_pq_asym_algs |= bench_pq_asym_opt[i].val;
7409                     bench_all = 0;
7410                     optMatched = 1;
7411                 }
7412             }
7413             /* Other known cryptographic algorithms */
7414             for (i=0; !optMatched && bench_other_opt[i].str != NULL; i++) {
7415                 if (string_matches(argv[1], bench_other_opt[i].str)) {
7416                     bench_other_algs |= bench_other_opt[i].val;
7417                     bench_all = 0;
7418                     optMatched = 1;
7419                 }
7420             }
7421 #endif
7422             if (!optMatched) {
7423                 printf("Option not recognized: %s\n", argv[1]);
7424                 Usage();
7425                 return 1;
7426             }
7427         }
7428         else {
7429             /* parse for block size */
7430             benchmark_configure(XATOI(argv[1]));
7431         }
7432         argc--;
7433         argv++;
7434     }
7435 #endif /* MAIN_NO_ARGS */
7436 
7437 #ifdef HAVE_STACK_SIZE
7438     ret = StackSizeCheck(NULL, benchmark_test);
7439 #else
7440     ret = benchmark_test(NULL);
7441 #endif
7442 
7443     return ret;
7444 }
7445 #endif /* !NO_MAIN_DRIVER */
7446 
7447 #else
7448     #ifndef NO_MAIN_DRIVER
main()7449         int main() { return 0; }
7450     #endif
7451 #endif /* !NO_CRYPT_BENCHMARK */
7452