quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

benchmark.c (44611B)


      1 /*
      2  *  Benchmark demonstration program
      3  *
      4  *  Copyright The Mbed TLS Contributors
      5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      6  */
      7 
      8 #include "mbedtls/build_info.h"
      9 
     10 #include "mbedtls/platform.h"
     11 
     12 #if !defined(MBEDTLS_HAVE_TIME)
     13 int main(void)
     14 {
     15     mbedtls_printf("MBEDTLS_HAVE_TIME not defined.\n");
     16     mbedtls_exit(0);
     17 }
     18 #else
     19 
     20 #include <string.h>
     21 #include <stdlib.h>
     22 
     23 #include "mbedtls/md5.h"
     24 #include "mbedtls/ripemd160.h"
     25 #include "mbedtls/sha1.h"
     26 #include "mbedtls/sha256.h"
     27 #include "mbedtls/sha512.h"
     28 #include "mbedtls/sha3.h"
     29 
     30 #include "mbedtls/des.h"
     31 #include "mbedtls/aes.h"
     32 #include "mbedtls/aria.h"
     33 #include "mbedtls/camellia.h"
     34 #include "mbedtls/chacha20.h"
     35 #include "mbedtls/gcm.h"
     36 #include "mbedtls/ccm.h"
     37 #include "mbedtls/chachapoly.h"
     38 #include "mbedtls/cmac.h"
     39 #include "mbedtls/poly1305.h"
     40 
     41 #include "mbedtls/ctr_drbg.h"
     42 #include "mbedtls/hmac_drbg.h"
     43 
     44 #include "mbedtls/rsa.h"
     45 #include "mbedtls/dhm.h"
     46 #include "mbedtls/ecdsa.h"
     47 #include "mbedtls/ecdh.h"
     48 
     49 #include "mbedtls/error.h"
     50 
     51 /* *INDENT-OFF* */
     52 #ifndef asm
     53 #define asm __asm
     54 #endif
     55 /* *INDENT-ON* */
     56 
     57 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
     58 
     59 #if defined(_MSC_VER)
     60 #pragma warning(disable : 5105) // warning inside winbase.h in C11 mode
     61 #endif
     62 
     63 #include <windows.h>
     64 #include <process.h>
     65 
     66 struct _hr_time {
     67     LARGE_INTEGER start;
     68 };
     69 
     70 #else
     71 
     72 #include <unistd.h>
     73 #include <sys/types.h>
     74 #include <sys/time.h>
     75 #include <signal.h>
     76 #include <time.h>
     77 
     78 struct _hr_time {
     79     struct timeval start;
     80 };
     81 
     82 #endif /* _WIN32 && !EFIX64 && !EFI32 */
     83 
     84 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
     85 #include "mbedtls/memory_buffer_alloc.h"
     86 #endif
     87 
     88 #ifdef MBEDTLS_TIMING_ALT
     89 void mbedtls_set_alarm(int seconds);
     90 unsigned long mbedtls_timing_hardclock(void);
     91 extern volatile int mbedtls_timing_alarmed;
     92 #else
     93 static void mbedtls_set_alarm(int seconds);
     94 static unsigned long mbedtls_timing_hardclock(void);
     95 #endif
     96 
     97 /*
     98  * For heap usage estimates, we need an estimate of the overhead per allocated
     99  * block. ptmalloc2/3 (used in gnu libc for instance) uses 2 size_t per block,
    100  * so use that as our baseline.
    101  */
    102 #define MEM_BLOCK_OVERHEAD  (2 * sizeof(size_t))
    103 
    104 /*
    105  * Size to use for the alloc buffer if MEMORY_BUFFER_ALLOC_C is defined.
    106  */
    107 #define HEAP_SIZE       (1u << 16)  /* 64k */
    108 
    109 #define BUFSIZE         1024
    110 #define HEADER_FORMAT   "  %-24s :  "
    111 #define TITLE_LEN       25
    112 
    113 #define OPTIONS                                                              \
    114     "md5, ripemd160, sha1, sha256, sha512,\n"                                \
    115     "sha3_224, sha3_256, sha3_384, sha3_512,\n"                              \
    116     "des3, des, camellia, chacha20,\n"                                       \
    117     "aes_cbc, aes_cfb128, aes_cfb8, aes_gcm, aes_ccm, aes_xts, chachapoly\n" \
    118     "aes_cmac, des3_cmac, poly1305\n"                                        \
    119     "ctr_drbg, hmac_drbg\n"                                                  \
    120     "rsa, dhm, ecdsa, ecdh.\n"
    121 
    122 #if defined(MBEDTLS_ERROR_C)
    123 #define PRINT_ERROR                                                     \
    124     mbedtls_strerror(ret, (char *) tmp, sizeof(tmp));          \
    125     mbedtls_printf("FAILED: %s\n", tmp);
    126 #else
    127 #define PRINT_ERROR                                                     \
    128     mbedtls_printf("FAILED: -0x%04x\n", (unsigned int) -ret);
    129 #endif
    130 
    131 #define TIME_AND_TSC(TITLE, CODE)                                     \
    132     do {                                                                    \
    133         unsigned long ii, jj, tsc;                                          \
    134         int ret = 0;                                                        \
    135                                                                         \
    136         mbedtls_printf(HEADER_FORMAT, TITLE);                             \
    137         fflush(stdout);                                                   \
    138                                                                         \
    139         mbedtls_set_alarm(1);                                             \
    140         for (ii = 1; ret == 0 && !mbedtls_timing_alarmed; ii++)           \
    141         {                                                                   \
    142             ret = CODE;                                                     \
    143         }                                                                   \
    144                                                                         \
    145         tsc = mbedtls_timing_hardclock();                                   \
    146         for (jj = 0; ret == 0 && jj < 1024; jj++)                          \
    147         {                                                                   \
    148             ret = CODE;                                                     \
    149         }                                                                   \
    150                                                                         \
    151         if (ret != 0)                                                      \
    152         {                                                                   \
    153             PRINT_ERROR;                                                    \
    154         }                                                                   \
    155         else                                                                \
    156         {                                                                   \
    157             mbedtls_printf("%9lu KiB/s,  %9lu cycles/byte\n",              \
    158                            ii * BUFSIZE / 1024,                           \
    159                            (mbedtls_timing_hardclock() - tsc)           \
    160                            / (jj * BUFSIZE));                          \
    161         }                                                                   \
    162     } while (0)
    163 
    164 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG)
    165 
    166 /* How much space to reserve for the title when printing heap usage results.
    167  * Updated manually as the output of the following command:
    168  *
    169  *  sed -n 's/.*[T]IME_PUBLIC.*"\(.*\)",/\1/p' programs/test/benchmark.c |
    170  *      awk '{print length+3}' | sort -rn | head -n1
    171  *
    172  * This computes the maximum length of a title +3, because we appends "/s" and
    173  * want at least one space. (If the value is too small, the only consequence
    174  * is poor alignment.) */
    175 #define TITLE_SPACE 17
    176 
    177 #define MEMORY_MEASURE_INIT                                             \
    178     size_t max_used, max_blocks, max_bytes;                             \
    179     size_t prv_used, prv_blocks;                                        \
    180     size_t alloc_cnt, free_cnt, prv_alloc, prv_free;                    \
    181     mbedtls_memory_buffer_alloc_cur_get(&prv_used, &prv_blocks);      \
    182     mbedtls_memory_buffer_alloc_max_reset();
    183 
    184 #define MEMORY_MEASURE_RESET                                            \
    185     mbedtls_memory_buffer_alloc_count_get(&prv_alloc, &prv_free);
    186 
    187 #define MEMORY_MEASURE_PRINT(title_len)                               \
    188     mbedtls_memory_buffer_alloc_max_get(&max_used, &max_blocks);      \
    189     mbedtls_memory_buffer_alloc_count_get(&alloc_cnt, &free_cnt);     \
    190     ii = TITLE_SPACE > (title_len) ? TITLE_SPACE - (title_len) : 1;     \
    191     while (ii--) mbedtls_printf(" ");                                \
    192     max_used -= prv_used;                                               \
    193     max_blocks -= prv_blocks;                                           \
    194     max_bytes = max_used + MEM_BLOCK_OVERHEAD * max_blocks;             \
    195     mbedtls_printf("%6u heap bytes, %6u allocs",                       \
    196                    (unsigned) max_bytes,                               \
    197                    (unsigned) (alloc_cnt - prv_alloc));
    198 
    199 #else
    200 #define MEMORY_MEASURE_INIT
    201 #define MEMORY_MEASURE_RESET
    202 #define MEMORY_MEASURE_PRINT(title_len)
    203 #endif
    204 
    205 #define TIME_PUBLIC(TITLE, TYPE, CODE)                                \
    206     do {                                                                    \
    207         unsigned long ii;                                                   \
    208         int ret;                                                            \
    209         MEMORY_MEASURE_INIT;                                                \
    210                                                                         \
    211         mbedtls_printf(HEADER_FORMAT, TITLE);                             \
    212         fflush(stdout);                                                   \
    213         mbedtls_set_alarm(3);                                             \
    214                                                                         \
    215         ret = 0;                                                            \
    216         for (ii = 1; !mbedtls_timing_alarmed && !ret; ii++)             \
    217         {                                                                   \
    218             MEMORY_MEASURE_RESET;                                           \
    219             CODE;                                                           \
    220         }                                                                   \
    221                                                                         \
    222         if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED)               \
    223         {                                                                   \
    224             mbedtls_printf("Feature Not Supported. Skipping.\n");         \
    225             ret = 0;                                                        \
    226         }                                                                   \
    227         else if (ret != 0)                                                 \
    228         {                                                                   \
    229             PRINT_ERROR;                                                    \
    230         }                                                                   \
    231         else                                                                \
    232         {                                                                   \
    233             mbedtls_printf("%6lu " TYPE "/s", ii / 3);                    \
    234             MEMORY_MEASURE_PRINT(sizeof(TYPE) + 1);                     \
    235             mbedtls_printf("\n");                                         \
    236         }                                                                   \
    237     } while (0)
    238 
    239 #if !defined(MBEDTLS_TIMING_ALT)
    240 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
    241     (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
    242 
    243 #define HAVE_HARDCLOCK
    244 
    245 static unsigned long mbedtls_timing_hardclock(void)
    246 {
    247     unsigned long tsc;
    248     __asm   rdtsc
    249     __asm   mov[tsc], eax
    250     return tsc;
    251 }
    252 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    253           ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */
    254 
    255 /* some versions of mingw-64 have 32-bit longs even on x84_64 */
    256 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
    257     defined(__GNUC__) && (defined(__i386__) || (                       \
    258     (defined(__amd64__) || defined(__x86_64__)) && __SIZEOF_LONG__ == 4))
    259 
    260 #define HAVE_HARDCLOCK
    261 
    262 static unsigned long mbedtls_timing_hardclock(void)
    263 {
    264     unsigned long lo, hi;
    265     asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
    266     return lo;
    267 }
    268 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    269           __GNUC__ && __i386__ */
    270 
    271 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
    272     defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
    273 
    274 #define HAVE_HARDCLOCK
    275 
    276 static unsigned long mbedtls_timing_hardclock(void)
    277 {
    278     unsigned long lo, hi;
    279     asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
    280     return lo | (hi << 32);
    281 }
    282 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    283           __GNUC__ && ( __amd64__ || __x86_64__ ) */
    284 
    285 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
    286     defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
    287 
    288 #define HAVE_HARDCLOCK
    289 
    290 static unsigned long mbedtls_timing_hardclock(void)
    291 {
    292     unsigned long tbl, tbu0, tbu1;
    293 
    294     do {
    295         asm volatile ("mftbu %0" : "=r" (tbu0));
    296         asm volatile ("mftb  %0" : "=r" (tbl));
    297         asm volatile ("mftbu %0" : "=r" (tbu1));
    298     } while (tbu0 != tbu1);
    299 
    300     return tbl;
    301 }
    302 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    303           __GNUC__ && ( __powerpc__ || __ppc__ ) */
    304 
    305 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
    306     defined(__GNUC__) && defined(__sparc64__)
    307 
    308 #if defined(__OpenBSD__)
    309 #warning OpenBSD does not allow access to tick register using software version instead
    310 #else
    311 #define HAVE_HARDCLOCK
    312 
    313 static unsigned long mbedtls_timing_hardclock(void)
    314 {
    315     unsigned long tick;
    316     asm volatile ("rdpr %%tick, %0;" : "=&r" (tick));
    317     return tick;
    318 }
    319 #endif /* __OpenBSD__ */
    320 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    321           __GNUC__ && __sparc64__ */
    322 
    323 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&  \
    324     defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__)
    325 
    326 #define HAVE_HARDCLOCK
    327 
    328 static unsigned long mbedtls_timing_hardclock(void)
    329 {
    330     unsigned long tick;
    331     asm volatile (".byte 0x83, 0x41, 0x00, 0x00");
    332     asm volatile ("mov   %%g1, %0" : "=r" (tick));
    333     return tick;
    334 }
    335 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    336           __GNUC__ && __sparc__ && !__sparc64__ */
    337 
    338 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
    339     defined(__GNUC__) && defined(__alpha__)
    340 
    341 #define HAVE_HARDCLOCK
    342 
    343 static unsigned long mbedtls_timing_hardclock(void)
    344 {
    345     unsigned long cc;
    346     asm volatile ("rpcc %0" : "=r" (cc));
    347     return cc & 0xFFFFFFFF;
    348 }
    349 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    350           __GNUC__ && __alpha__ */
    351 
    352 #if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) &&      \
    353     defined(__GNUC__) && defined(__ia64__)
    354 
    355 #define HAVE_HARDCLOCK
    356 
    357 static unsigned long mbedtls_timing_hardclock(void)
    358 {
    359     unsigned long itc;
    360     asm volatile ("mov %0 = ar.itc" : "=r" (itc));
    361     return itc;
    362 }
    363 #endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM &&
    364           __GNUC__ && __ia64__ */
    365 
    366 #if !defined(HAVE_HARDCLOCK) && defined(_WIN32) && \
    367     !defined(EFIX64) && !defined(EFI32)
    368 
    369 #define HAVE_HARDCLOCK
    370 
    371 static unsigned long mbedtls_timing_hardclock(void)
    372 {
    373     LARGE_INTEGER offset;
    374 
    375     QueryPerformanceCounter(&offset);
    376 
    377     return (unsigned long) (offset.QuadPart);
    378 }
    379 #endif /* !HAVE_HARDCLOCK && _WIN32 && !EFIX64 && !EFI32 */
    380 
    381 #if !defined(HAVE_HARDCLOCK)
    382 
    383 #define HAVE_HARDCLOCK
    384 
    385 static int hardclock_init = 0;
    386 static struct timeval tv_init;
    387 
    388 static unsigned long mbedtls_timing_hardclock(void)
    389 {
    390     struct timeval tv_cur;
    391 
    392     if (hardclock_init == 0) {
    393         gettimeofday(&tv_init, NULL);
    394         hardclock_init = 1;
    395     }
    396 
    397     gettimeofday(&tv_cur, NULL);
    398     return (tv_cur.tv_sec  - tv_init.tv_sec) * 1000000U
    399            + (tv_cur.tv_usec - tv_init.tv_usec);
    400 }
    401 #endif /* !HAVE_HARDCLOCK */
    402 
    403 volatile int mbedtls_timing_alarmed = 0;
    404 
    405 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
    406 
    407 /* It's OK to use a global because alarm() is supposed to be global anyway */
    408 static DWORD alarmMs;
    409 
    410 static void TimerProc(void *TimerContext)
    411 {
    412     (void) TimerContext;
    413     Sleep(alarmMs);
    414     mbedtls_timing_alarmed = 1;
    415     /* _endthread will be called implicitly on return
    416      * That ensures execution of thread function's epilogue */
    417 }
    418 
    419 static void mbedtls_set_alarm(int seconds)
    420 {
    421     if (seconds == 0) {
    422         /* No need to create a thread for this simple case.
    423          * Also, this shorcut is more reliable at least on MinGW32 */
    424         mbedtls_timing_alarmed = 1;
    425         return;
    426     }
    427 
    428     mbedtls_timing_alarmed = 0;
    429     alarmMs = seconds * 1000;
    430     (void) _beginthread(TimerProc, 0, NULL);
    431 }
    432 
    433 #else /* _WIN32 && !EFIX64 && !EFI32 */
    434 
    435 static void sighandler(int signum)
    436 {
    437     mbedtls_timing_alarmed = 1;
    438     signal(signum, sighandler);
    439 }
    440 
    441 static void mbedtls_set_alarm(int seconds)
    442 {
    443     mbedtls_timing_alarmed = 0;
    444     signal(SIGALRM, sighandler);
    445     alarm(seconds);
    446     if (seconds == 0) {
    447         /* alarm(0) cancelled any previous pending alarm, but the
    448            handler won't fire, so raise the flag straight away. */
    449         mbedtls_timing_alarmed = 1;
    450     }
    451 }
    452 
    453 #endif /* _WIN32 && !EFIX64 && !EFI32 */
    454 #endif /* !MBEDTLS_TIMING_ALT */
    455 
    456 static int myrand(void *rng_state, unsigned char *output, size_t len)
    457 {
    458     size_t use_len;
    459     int rnd;
    460 
    461     if (rng_state != NULL) {
    462         rng_state  = NULL;
    463     }
    464 
    465     while (len > 0) {
    466         use_len = len;
    467         if (use_len > sizeof(int)) {
    468             use_len = sizeof(int);
    469         }
    470 
    471         rnd = rand();
    472         memcpy(output, &rnd, use_len);
    473         output += use_len;
    474         len -= use_len;
    475     }
    476 
    477     return 0;
    478 }
    479 
    480 #define CHECK_AND_CONTINUE(R)                                         \
    481     {                                                                   \
    482         int CHECK_AND_CONTINUE_ret = (R);                             \
    483         if (CHECK_AND_CONTINUE_ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) { \
    484             mbedtls_printf("Feature not supported. Skipping.\n");     \
    485             continue;                                                   \
    486         }                                                               \
    487         else if (CHECK_AND_CONTINUE_ret != 0) {                        \
    488             mbedtls_exit(1);                                          \
    489         }                                                               \
    490     }
    491 
    492 #if defined(MBEDTLS_ECP_C)
    493 static int set_ecp_curve(const char *string, mbedtls_ecp_curve_info *curve)
    494 {
    495     const mbedtls_ecp_curve_info *found =
    496         mbedtls_ecp_curve_info_from_name(string);
    497     if (found != NULL) {
    498         *curve = *found;
    499         return 1;
    500     } else {
    501         return 0;
    502     }
    503 }
    504 #endif
    505 
    506 unsigned char buf[BUFSIZE];
    507 
    508 typedef struct {
    509     char md5, ripemd160, sha1, sha256, sha512,
    510          sha3_224, sha3_256, sha3_384, sha3_512,
    511          des3, des,
    512          aes_cbc, aes_cfb128, aes_cfb8, aes_ctr, aes_gcm, aes_ccm, aes_xts, chachapoly,
    513          aes_cmac, des3_cmac,
    514          aria, camellia, chacha20,
    515          poly1305,
    516          ctr_drbg, hmac_drbg,
    517          rsa, dhm, ecdsa, ecdh;
    518 } todo_list;
    519 
    520 
    521 int main(int argc, char *argv[])
    522 {
    523     int i;
    524     unsigned char tmp[200];
    525     char title[TITLE_LEN];
    526     todo_list todo;
    527 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
    528     unsigned char alloc_buf[HEAP_SIZE] = { 0 };
    529 #endif
    530 #if defined(MBEDTLS_ECP_C)
    531     mbedtls_ecp_curve_info single_curve[2] = {
    532         { MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
    533         { MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
    534     };
    535     const mbedtls_ecp_curve_info *curve_list = mbedtls_ecp_curve_list();
    536 #endif
    537 
    538 #if defined(MBEDTLS_ECP_C)
    539     (void) curve_list; /* Unused in some configurations where no benchmark uses ECC */
    540 #endif
    541 
    542     if (argc <= 1) {
    543         memset(&todo, 1, sizeof(todo));
    544     } else {
    545         memset(&todo, 0, sizeof(todo));
    546 
    547         for (i = 1; i < argc; i++) {
    548             if (strcmp(argv[i], "md5") == 0) {
    549                 todo.md5 = 1;
    550             } else if (strcmp(argv[i], "ripemd160") == 0) {
    551                 todo.ripemd160 = 1;
    552             } else if (strcmp(argv[i], "sha1") == 0) {
    553                 todo.sha1 = 1;
    554             } else if (strcmp(argv[i], "sha256") == 0) {
    555                 todo.sha256 = 1;
    556             } else if (strcmp(argv[i], "sha512") == 0) {
    557                 todo.sha512 = 1;
    558             } else if (strcmp(argv[i], "sha3_224") == 0) {
    559                 todo.sha3_224 = 1;
    560             } else if (strcmp(argv[i], "sha3_256") == 0) {
    561                 todo.sha3_256 = 1;
    562             } else if (strcmp(argv[i], "sha3_384") == 0) {
    563                 todo.sha3_384 = 1;
    564             } else if (strcmp(argv[i], "sha3_512") == 0) {
    565                 todo.sha3_512 = 1;
    566             } else if (strcmp(argv[i], "des3") == 0) {
    567                 todo.des3 = 1;
    568             } else if (strcmp(argv[i], "des") == 0) {
    569                 todo.des = 1;
    570             } else if (strcmp(argv[i], "aes_cbc") == 0) {
    571                 todo.aes_cbc = 1;
    572             } else if (strcmp(argv[i], "aes_cfb128") == 0) {
    573                 todo.aes_cfb128 = 1;
    574             } else if (strcmp(argv[i], "aes_cfb8") == 0) {
    575                 todo.aes_cfb8 = 1;
    576             } else if (strcmp(argv[i], "aes_ctr") == 0) {
    577                 todo.aes_ctr = 1;
    578             } else if (strcmp(argv[i], "aes_xts") == 0) {
    579                 todo.aes_xts = 1;
    580             } else if (strcmp(argv[i], "aes_gcm") == 0) {
    581                 todo.aes_gcm = 1;
    582             } else if (strcmp(argv[i], "aes_ccm") == 0) {
    583                 todo.aes_ccm = 1;
    584             } else if (strcmp(argv[i], "chachapoly") == 0) {
    585                 todo.chachapoly = 1;
    586             } else if (strcmp(argv[i], "aes_cmac") == 0) {
    587                 todo.aes_cmac = 1;
    588             } else if (strcmp(argv[i], "des3_cmac") == 0) {
    589                 todo.des3_cmac = 1;
    590             } else if (strcmp(argv[i], "aria") == 0) {
    591                 todo.aria = 1;
    592             } else if (strcmp(argv[i], "camellia") == 0) {
    593                 todo.camellia = 1;
    594             } else if (strcmp(argv[i], "chacha20") == 0) {
    595                 todo.chacha20 = 1;
    596             } else if (strcmp(argv[i], "poly1305") == 0) {
    597                 todo.poly1305 = 1;
    598             } else if (strcmp(argv[i], "ctr_drbg") == 0) {
    599                 todo.ctr_drbg = 1;
    600             } else if (strcmp(argv[i], "hmac_drbg") == 0) {
    601                 todo.hmac_drbg = 1;
    602             } else if (strcmp(argv[i], "rsa") == 0) {
    603                 todo.rsa = 1;
    604             } else if (strcmp(argv[i], "dhm") == 0) {
    605                 todo.dhm = 1;
    606             } else if (strcmp(argv[i], "ecdsa") == 0) {
    607                 todo.ecdsa = 1;
    608             } else if (strcmp(argv[i], "ecdh") == 0) {
    609                 todo.ecdh = 1;
    610             }
    611 #if defined(MBEDTLS_ECP_C)
    612             else if (set_ecp_curve(argv[i], single_curve)) {
    613                 curve_list = single_curve;
    614             }
    615 #endif
    616             else {
    617                 mbedtls_printf("Unrecognized option: %s\n", argv[i]);
    618                 mbedtls_printf("Available options: " OPTIONS);
    619             }
    620         }
    621     }
    622 
    623     mbedtls_printf("\n");
    624 
    625 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
    626     mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf));
    627 #endif
    628     memset(buf, 0xAA, sizeof(buf));
    629     memset(tmp, 0xBB, sizeof(tmp));
    630 
    631     /* Avoid "unused static function" warning in configurations without
    632      * symmetric crypto. */
    633     (void) mbedtls_timing_hardclock;
    634 
    635 #if defined(MBEDTLS_MD5_C)
    636     if (todo.md5) {
    637         TIME_AND_TSC("MD5", mbedtls_md5(buf, BUFSIZE, tmp));
    638     }
    639 #endif
    640 
    641 #if defined(MBEDTLS_RIPEMD160_C)
    642     if (todo.ripemd160) {
    643         TIME_AND_TSC("RIPEMD160", mbedtls_ripemd160(buf, BUFSIZE, tmp));
    644     }
    645 #endif
    646 
    647 #if defined(MBEDTLS_SHA1_C)
    648     if (todo.sha1) {
    649         TIME_AND_TSC("SHA-1", mbedtls_sha1(buf, BUFSIZE, tmp));
    650     }
    651 #endif
    652 
    653 #if defined(MBEDTLS_SHA256_C)
    654     if (todo.sha256) {
    655         TIME_AND_TSC("SHA-256", mbedtls_sha256(buf, BUFSIZE, tmp, 0));
    656     }
    657 #endif
    658 
    659 #if defined(MBEDTLS_SHA512_C)
    660     if (todo.sha512) {
    661         TIME_AND_TSC("SHA-512", mbedtls_sha512(buf, BUFSIZE, tmp, 0));
    662     }
    663 #endif
    664 #if defined(MBEDTLS_SHA3_C)
    665     if (todo.sha3_224) {
    666         TIME_AND_TSC("SHA3-224", mbedtls_sha3(MBEDTLS_SHA3_224, buf, BUFSIZE, tmp, 28));
    667     }
    668     if (todo.sha3_256) {
    669         TIME_AND_TSC("SHA3-256", mbedtls_sha3(MBEDTLS_SHA3_256, buf, BUFSIZE, tmp, 32));
    670     }
    671     if (todo.sha3_384) {
    672         TIME_AND_TSC("SHA3-384", mbedtls_sha3(MBEDTLS_SHA3_384, buf, BUFSIZE, tmp, 48));
    673     }
    674     if (todo.sha3_512) {
    675         TIME_AND_TSC("SHA3-512", mbedtls_sha3(MBEDTLS_SHA3_512, buf, BUFSIZE, tmp, 64));
    676     }
    677 #endif
    678 
    679 #if defined(MBEDTLS_DES_C)
    680 #if defined(MBEDTLS_CIPHER_MODE_CBC)
    681     if (todo.des3) {
    682         mbedtls_des3_context des3;
    683 
    684         mbedtls_des3_init(&des3);
    685         if (mbedtls_des3_set3key_enc(&des3, tmp) != 0) {
    686             mbedtls_exit(1);
    687         }
    688         TIME_AND_TSC("3DES",
    689                      mbedtls_des3_crypt_cbc(&des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf));
    690         mbedtls_des3_free(&des3);
    691     }
    692 
    693     if (todo.des) {
    694         mbedtls_des_context des;
    695 
    696         mbedtls_des_init(&des);
    697         if (mbedtls_des_setkey_enc(&des, tmp) != 0) {
    698             mbedtls_exit(1);
    699         }
    700         TIME_AND_TSC("DES",
    701                      mbedtls_des_crypt_cbc(&des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf));
    702         mbedtls_des_free(&des);
    703     }
    704 
    705 #endif /* MBEDTLS_CIPHER_MODE_CBC */
    706 #if defined(MBEDTLS_CMAC_C)
    707     if (todo.des3_cmac) {
    708         unsigned char output[8];
    709         const mbedtls_cipher_info_t *cipher_info;
    710 
    711         memset(buf, 0, sizeof(buf));
    712         memset(tmp, 0, sizeof(tmp));
    713 
    714         cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_EDE3_ECB);
    715 
    716         TIME_AND_TSC("3DES-CMAC",
    717                      mbedtls_cipher_cmac(cipher_info, tmp, 192, buf,
    718                                          BUFSIZE, output));
    719     }
    720 #endif /* MBEDTLS_CMAC_C */
    721 #endif /* MBEDTLS_DES_C */
    722 
    723 #if defined(MBEDTLS_AES_C)
    724 #if defined(MBEDTLS_CIPHER_MODE_CBC)
    725     if (todo.aes_cbc) {
    726         int keysize;
    727         mbedtls_aes_context aes;
    728 
    729         mbedtls_aes_init(&aes);
    730         for (keysize = 128; keysize <= 256; keysize += 64) {
    731             mbedtls_snprintf(title, sizeof(title), "AES-CBC-%d", keysize);
    732 
    733             memset(buf, 0, sizeof(buf));
    734             memset(tmp, 0, sizeof(tmp));
    735             CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
    736 
    737             TIME_AND_TSC(title,
    738                          mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf));
    739         }
    740         mbedtls_aes_free(&aes);
    741     }
    742 #endif
    743 #if defined(MBEDTLS_CIPHER_MODE_CFB)
    744     if (todo.aes_cfb128) {
    745         int keysize;
    746         size_t iv_off = 0;
    747         mbedtls_aes_context aes;
    748 
    749         mbedtls_aes_init(&aes);
    750         for (keysize = 128; keysize <= 256; keysize += 64) {
    751             mbedtls_snprintf(title, sizeof(title), "AES-CFB128-%d", keysize);
    752 
    753             memset(buf, 0, sizeof(buf));
    754             memset(tmp, 0, sizeof(tmp));
    755             CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
    756 
    757             TIME_AND_TSC(title,
    758                          mbedtls_aes_crypt_cfb128(&aes, MBEDTLS_AES_ENCRYPT, BUFSIZE,
    759                                                   &iv_off, tmp, buf, buf));
    760         }
    761         mbedtls_aes_free(&aes);
    762     }
    763     if (todo.aes_cfb8) {
    764         int keysize;
    765         mbedtls_aes_context aes;
    766 
    767         mbedtls_aes_init(&aes);
    768         for (keysize = 128; keysize <= 256; keysize += 64) {
    769             mbedtls_snprintf(title, sizeof(title), "AES-CFB8-%d", keysize);
    770 
    771             memset(buf, 0, sizeof(buf));
    772             memset(tmp, 0, sizeof(tmp));
    773             CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
    774 
    775             TIME_AND_TSC(title,
    776                          mbedtls_aes_crypt_cfb8(&aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf));
    777         }
    778         mbedtls_aes_free(&aes);
    779     }
    780 #endif
    781 #if defined(MBEDTLS_CIPHER_MODE_CTR)
    782     if (todo.aes_ctr) {
    783         int keysize;
    784         mbedtls_aes_context aes;
    785 
    786         uint8_t stream_block[16];
    787         size_t nc_off;
    788 
    789         mbedtls_aes_init(&aes);
    790         for (keysize = 128; keysize <= 256; keysize += 64) {
    791             mbedtls_snprintf(title, sizeof(title), "AES-CTR-%d", keysize);
    792 
    793             memset(buf, 0, sizeof(buf));
    794             memset(tmp, 0, sizeof(tmp));
    795             memset(stream_block, 0, sizeof(stream_block));
    796             nc_off = 0;
    797 
    798             CHECK_AND_CONTINUE(mbedtls_aes_setkey_enc(&aes, tmp, keysize));
    799 
    800             TIME_AND_TSC(title, mbedtls_aes_crypt_ctr(&aes, BUFSIZE, &nc_off, tmp, stream_block,
    801                                                       buf, buf));
    802         }
    803         mbedtls_aes_free(&aes);
    804     }
    805 #endif
    806 #if defined(MBEDTLS_CIPHER_MODE_XTS)
    807     if (todo.aes_xts) {
    808         int keysize;
    809         mbedtls_aes_xts_context ctx;
    810 
    811         mbedtls_aes_xts_init(&ctx);
    812         for (keysize = 128; keysize <= 256; keysize += 128) {
    813             mbedtls_snprintf(title, sizeof(title), "AES-XTS-%d", keysize);
    814 
    815             memset(buf, 0, sizeof(buf));
    816             memset(tmp, 0, sizeof(tmp));
    817             CHECK_AND_CONTINUE(mbedtls_aes_xts_setkey_enc(&ctx, tmp, keysize * 2));
    818 
    819             TIME_AND_TSC(title,
    820                          mbedtls_aes_crypt_xts(&ctx, MBEDTLS_AES_ENCRYPT, BUFSIZE,
    821                                                tmp, buf, buf));
    822 
    823             mbedtls_aes_xts_free(&ctx);
    824         }
    825     }
    826 #endif
    827 #if defined(MBEDTLS_GCM_C)
    828     if (todo.aes_gcm) {
    829         int keysize;
    830         mbedtls_gcm_context gcm;
    831 
    832         mbedtls_gcm_init(&gcm);
    833         for (keysize = 128; keysize <= 256; keysize += 64) {
    834             mbedtls_snprintf(title, sizeof(title), "AES-GCM-%d", keysize);
    835 
    836             memset(buf, 0, sizeof(buf));
    837             memset(tmp, 0, sizeof(tmp));
    838             mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, tmp, keysize);
    839 
    840             TIME_AND_TSC(title,
    841                          mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, BUFSIZE, tmp,
    842                                                    12, NULL, 0, buf, buf, 16, tmp));
    843 
    844             mbedtls_gcm_free(&gcm);
    845         }
    846     }
    847 #endif
    848 #if defined(MBEDTLS_CCM_C)
    849     if (todo.aes_ccm) {
    850         int keysize;
    851         mbedtls_ccm_context ccm;
    852 
    853         mbedtls_ccm_init(&ccm);
    854         for (keysize = 128; keysize <= 256; keysize += 64) {
    855             mbedtls_snprintf(title, sizeof(title), "AES-CCM-%d", keysize);
    856 
    857             memset(buf, 0, sizeof(buf));
    858             memset(tmp, 0, sizeof(tmp));
    859             mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, tmp, keysize);
    860 
    861             TIME_AND_TSC(title,
    862                          mbedtls_ccm_encrypt_and_tag(&ccm, BUFSIZE, tmp,
    863                                                      12, NULL, 0, buf, buf, tmp, 16));
    864 
    865             mbedtls_ccm_free(&ccm);
    866         }
    867     }
    868 #endif
    869 #if defined(MBEDTLS_CHACHAPOLY_C)
    870     if (todo.chachapoly) {
    871         mbedtls_chachapoly_context chachapoly;
    872 
    873         mbedtls_chachapoly_init(&chachapoly);
    874         memset(buf, 0, sizeof(buf));
    875         memset(tmp, 0, sizeof(tmp));
    876 
    877         mbedtls_snprintf(title, sizeof(title), "ChaCha20-Poly1305");
    878 
    879         mbedtls_chachapoly_setkey(&chachapoly, tmp);
    880 
    881         TIME_AND_TSC(title,
    882                      mbedtls_chachapoly_encrypt_and_tag(&chachapoly,
    883                                                         BUFSIZE, tmp, NULL, 0, buf, buf, tmp));
    884 
    885         mbedtls_chachapoly_free(&chachapoly);
    886     }
    887 #endif
    888 #if defined(MBEDTLS_CMAC_C)
    889     if (todo.aes_cmac) {
    890         unsigned char output[16];
    891         const mbedtls_cipher_info_t *cipher_info;
    892         mbedtls_cipher_type_t cipher_type;
    893         int keysize;
    894 
    895         for (keysize = 128, cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
    896              keysize <= 256;
    897              keysize += 64, cipher_type++) {
    898             mbedtls_snprintf(title, sizeof(title), "AES-CMAC-%d", keysize);
    899 
    900             memset(buf, 0, sizeof(buf));
    901             memset(tmp, 0, sizeof(tmp));
    902 
    903             cipher_info = mbedtls_cipher_info_from_type(cipher_type);
    904 
    905             TIME_AND_TSC(title,
    906                          mbedtls_cipher_cmac(cipher_info, tmp, keysize,
    907                                              buf, BUFSIZE, output));
    908         }
    909 
    910         memset(buf, 0, sizeof(buf));
    911         memset(tmp, 0, sizeof(tmp));
    912         TIME_AND_TSC("AES-CMAC-PRF-128",
    913                      mbedtls_aes_cmac_prf_128(tmp, 16, buf, BUFSIZE,
    914                                               output));
    915     }
    916 #endif /* MBEDTLS_CMAC_C */
    917 #endif /* MBEDTLS_AES_C */
    918 
    919 #if defined(MBEDTLS_ARIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
    920     if (todo.aria) {
    921         int keysize;
    922         mbedtls_aria_context aria;
    923 
    924         mbedtls_aria_init(&aria);
    925         for (keysize = 128; keysize <= 256; keysize += 64) {
    926             mbedtls_snprintf(title, sizeof(title), "ARIA-CBC-%d", keysize);
    927 
    928             memset(buf, 0, sizeof(buf));
    929             memset(tmp, 0, sizeof(tmp));
    930             mbedtls_aria_setkey_enc(&aria, tmp, keysize);
    931 
    932             TIME_AND_TSC(title,
    933                          mbedtls_aria_crypt_cbc(&aria, MBEDTLS_ARIA_ENCRYPT,
    934                                                 BUFSIZE, tmp, buf, buf));
    935         }
    936         mbedtls_aria_free(&aria);
    937     }
    938 #endif
    939 
    940 #if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
    941     if (todo.camellia) {
    942         int keysize;
    943         mbedtls_camellia_context camellia;
    944 
    945         mbedtls_camellia_init(&camellia);
    946         for (keysize = 128; keysize <= 256; keysize += 64) {
    947             mbedtls_snprintf(title, sizeof(title), "CAMELLIA-CBC-%d", keysize);
    948 
    949             memset(buf, 0, sizeof(buf));
    950             memset(tmp, 0, sizeof(tmp));
    951             mbedtls_camellia_setkey_enc(&camellia, tmp, keysize);
    952 
    953             TIME_AND_TSC(title,
    954                          mbedtls_camellia_crypt_cbc(&camellia, MBEDTLS_CAMELLIA_ENCRYPT,
    955                                                     BUFSIZE, tmp, buf, buf));
    956         }
    957         mbedtls_camellia_free(&camellia);
    958     }
    959 #endif
    960 
    961 #if defined(MBEDTLS_CHACHA20_C)
    962     if (todo.chacha20) {
    963         TIME_AND_TSC("ChaCha20", mbedtls_chacha20_crypt(buf, buf, 0U, BUFSIZE, buf, buf));
    964     }
    965 #endif
    966 
    967 #if defined(MBEDTLS_POLY1305_C)
    968     if (todo.poly1305) {
    969         TIME_AND_TSC("Poly1305", mbedtls_poly1305_mac(buf, buf, BUFSIZE, buf));
    970     }
    971 #endif
    972 
    973 #if defined(MBEDTLS_CTR_DRBG_C)
    974     if (todo.ctr_drbg) {
    975         mbedtls_ctr_drbg_context ctr_drbg;
    976 
    977         mbedtls_ctr_drbg_init(&ctr_drbg);
    978         if (mbedtls_ctr_drbg_seed(&ctr_drbg, myrand, NULL, NULL, 0) != 0) {
    979             mbedtls_exit(1);
    980         }
    981         TIME_AND_TSC("CTR_DRBG (NOPR)",
    982                      mbedtls_ctr_drbg_random(&ctr_drbg, buf, BUFSIZE));
    983         mbedtls_ctr_drbg_free(&ctr_drbg);
    984 
    985         mbedtls_ctr_drbg_init(&ctr_drbg);
    986         if (mbedtls_ctr_drbg_seed(&ctr_drbg, myrand, NULL, NULL, 0) != 0) {
    987             mbedtls_exit(1);
    988         }
    989         mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON);
    990         TIME_AND_TSC("CTR_DRBG (PR)",
    991                      mbedtls_ctr_drbg_random(&ctr_drbg, buf, BUFSIZE));
    992         mbedtls_ctr_drbg_free(&ctr_drbg);
    993     }
    994 #endif
    995 
    996 #if defined(MBEDTLS_HMAC_DRBG_C) && \
    997     (defined(MBEDTLS_SHA1_C) || defined(MBEDTLS_SHA256_C))
    998     if (todo.hmac_drbg) {
    999         mbedtls_hmac_drbg_context hmac_drbg;
   1000         const mbedtls_md_info_t *md_info;
   1001 
   1002         mbedtls_hmac_drbg_init(&hmac_drbg);
   1003 
   1004 #if defined(MBEDTLS_SHA1_C)
   1005         if ((md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1)) == NULL) {
   1006             mbedtls_exit(1);
   1007         }
   1008 
   1009         if (mbedtls_hmac_drbg_seed(&hmac_drbg, md_info, myrand, NULL, NULL, 0) != 0) {
   1010             mbedtls_exit(1);
   1011         }
   1012         TIME_AND_TSC("HMAC_DRBG SHA-1 (NOPR)",
   1013                      mbedtls_hmac_drbg_random(&hmac_drbg, buf, BUFSIZE));
   1014 
   1015         if (mbedtls_hmac_drbg_seed(&hmac_drbg, md_info, myrand, NULL, NULL, 0) != 0) {
   1016             mbedtls_exit(1);
   1017         }
   1018         mbedtls_hmac_drbg_set_prediction_resistance(&hmac_drbg,
   1019                                                     MBEDTLS_HMAC_DRBG_PR_ON);
   1020         TIME_AND_TSC("HMAC_DRBG SHA-1 (PR)",
   1021                      mbedtls_hmac_drbg_random(&hmac_drbg, buf, BUFSIZE));
   1022 #endif
   1023 
   1024 #if defined(MBEDTLS_SHA256_C)
   1025         if ((md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256)) == NULL) {
   1026             mbedtls_exit(1);
   1027         }
   1028 
   1029         if (mbedtls_hmac_drbg_seed(&hmac_drbg, md_info, myrand, NULL, NULL, 0) != 0) {
   1030             mbedtls_exit(1);
   1031         }
   1032         TIME_AND_TSC("HMAC_DRBG SHA-256 (NOPR)",
   1033                      mbedtls_hmac_drbg_random(&hmac_drbg, buf, BUFSIZE));
   1034 
   1035         if (mbedtls_hmac_drbg_seed(&hmac_drbg, md_info, myrand, NULL, NULL, 0) != 0) {
   1036             mbedtls_exit(1);
   1037         }
   1038         mbedtls_hmac_drbg_set_prediction_resistance(&hmac_drbg,
   1039                                                     MBEDTLS_HMAC_DRBG_PR_ON);
   1040         TIME_AND_TSC("HMAC_DRBG SHA-256 (PR)",
   1041                      mbedtls_hmac_drbg_random(&hmac_drbg, buf, BUFSIZE));
   1042 #endif
   1043         mbedtls_hmac_drbg_free(&hmac_drbg);
   1044     }
   1045 #endif /* MBEDTLS_HMAC_DRBG_C && ( MBEDTLS_SHA1_C || MBEDTLS_SHA256_C ) */
   1046 
   1047 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
   1048     if (todo.rsa) {
   1049         int keysize;
   1050         mbedtls_rsa_context rsa;
   1051 
   1052         for (keysize = 2048; keysize <= 4096; keysize += 1024) {
   1053             mbedtls_snprintf(title, sizeof(title), "RSA-%d", keysize);
   1054 
   1055             mbedtls_rsa_init(&rsa);
   1056             mbedtls_rsa_gen_key(&rsa, myrand, NULL, keysize, 65537);
   1057 
   1058             TIME_PUBLIC(title, " public",
   1059                         buf[0] = 0;
   1060                         ret = mbedtls_rsa_public(&rsa, buf, buf));
   1061 
   1062             TIME_PUBLIC(title, "private",
   1063                         buf[0] = 0;
   1064                         ret = mbedtls_rsa_private(&rsa, myrand, NULL, buf, buf));
   1065 
   1066             mbedtls_rsa_free(&rsa);
   1067         }
   1068     }
   1069 #endif
   1070 
   1071 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_BIGNUM_C)
   1072     if (todo.dhm) {
   1073         int dhm_sizes[] = { 2048, 3072 };
   1074         static const unsigned char dhm_P_2048[] =
   1075             MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
   1076         static const unsigned char dhm_P_3072[] =
   1077             MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN;
   1078         static const unsigned char dhm_G_2048[] =
   1079             MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
   1080         static const unsigned char dhm_G_3072[] =
   1081             MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN;
   1082 
   1083         const unsigned char *dhm_P[] = { dhm_P_2048, dhm_P_3072 };
   1084         const size_t dhm_P_size[] = { sizeof(dhm_P_2048),
   1085                                       sizeof(dhm_P_3072) };
   1086 
   1087         const unsigned char *dhm_G[] = { dhm_G_2048, dhm_G_3072 };
   1088         const size_t dhm_G_size[] = { sizeof(dhm_G_2048),
   1089                                       sizeof(dhm_G_3072) };
   1090 
   1091         mbedtls_dhm_context dhm;
   1092         size_t olen;
   1093         size_t n;
   1094         mbedtls_mpi P, G;
   1095         mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
   1096 
   1097         for (i = 0; (size_t) i < sizeof(dhm_sizes) / sizeof(dhm_sizes[0]); i++) {
   1098             mbedtls_dhm_init(&dhm);
   1099 
   1100             if (mbedtls_mpi_read_binary(&P, dhm_P[i],
   1101                                         dhm_P_size[i]) != 0 ||
   1102                 mbedtls_mpi_read_binary(&G, dhm_G[i],
   1103                                         dhm_G_size[i]) != 0 ||
   1104                 mbedtls_dhm_set_group(&dhm, &P, &G) != 0) {
   1105                 mbedtls_exit(1);
   1106             }
   1107 
   1108             n = mbedtls_dhm_get_len(&dhm);
   1109             mbedtls_dhm_make_public(&dhm, (int) n, buf, n, myrand, NULL);
   1110 
   1111             if (mbedtls_dhm_read_public(&dhm, buf, n) != 0) {
   1112                 mbedtls_exit(1);
   1113             }
   1114 
   1115             mbedtls_snprintf(title, sizeof(title), "DHE-%d", dhm_sizes[i]);
   1116             TIME_PUBLIC(title, "handshake",
   1117                         ret |= mbedtls_dhm_make_public(&dhm, (int) n, buf, n,
   1118                                                        myrand, NULL);
   1119                         ret |=
   1120                             mbedtls_dhm_calc_secret(&dhm, buf, sizeof(buf), &olen, myrand, NULL));
   1121 
   1122             mbedtls_snprintf(title, sizeof(title), "DH-%d", dhm_sizes[i]);
   1123             TIME_PUBLIC(title, "handshake",
   1124                         ret |=
   1125                             mbedtls_dhm_calc_secret(&dhm, buf, sizeof(buf), &olen, myrand, NULL));
   1126 
   1127             mbedtls_dhm_free(&dhm);
   1128             mbedtls_mpi_free(&P), mbedtls_mpi_free(&G);
   1129         }
   1130     }
   1131 #endif
   1132 
   1133 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA256_C)
   1134     if (todo.ecdsa) {
   1135         mbedtls_ecdsa_context ecdsa;
   1136         const mbedtls_ecp_curve_info *curve_info;
   1137         size_t sig_len;
   1138 
   1139         memset(buf, 0x2A, sizeof(buf));
   1140 
   1141         for (curve_info = curve_list;
   1142              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
   1143              curve_info++) {
   1144             if (!mbedtls_ecdsa_can_do(curve_info->grp_id)) {
   1145                 continue;
   1146             }
   1147 
   1148             mbedtls_ecdsa_init(&ecdsa);
   1149 
   1150             if (mbedtls_ecdsa_genkey(&ecdsa, curve_info->grp_id, myrand, NULL) != 0) {
   1151                 mbedtls_exit(1);
   1152             }
   1153 
   1154             mbedtls_snprintf(title, sizeof(title), "ECDSA-%s",
   1155                              curve_info->name);
   1156             TIME_PUBLIC(title,
   1157                         "sign",
   1158                         ret =
   1159                             mbedtls_ecdsa_write_signature(&ecdsa, MBEDTLS_MD_SHA256, buf,
   1160                                                           curve_info->bit_size,
   1161                                                           tmp, sizeof(tmp), &sig_len, myrand,
   1162                                                           NULL));
   1163 
   1164             mbedtls_ecdsa_free(&ecdsa);
   1165         }
   1166 
   1167         for (curve_info = curve_list;
   1168              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
   1169              curve_info++) {
   1170             if (!mbedtls_ecdsa_can_do(curve_info->grp_id)) {
   1171                 continue;
   1172             }
   1173 
   1174             mbedtls_ecdsa_init(&ecdsa);
   1175 
   1176             if (mbedtls_ecdsa_genkey(&ecdsa, curve_info->grp_id, myrand, NULL) != 0 ||
   1177                 mbedtls_ecdsa_write_signature(&ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
   1178                                               tmp, sizeof(tmp), &sig_len, myrand, NULL) != 0) {
   1179                 mbedtls_exit(1);
   1180             }
   1181 
   1182             mbedtls_snprintf(title, sizeof(title), "ECDSA-%s",
   1183                              curve_info->name);
   1184             TIME_PUBLIC(title, "verify",
   1185                         ret = mbedtls_ecdsa_read_signature(&ecdsa, buf, curve_info->bit_size,
   1186                                                            tmp, sig_len));
   1187 
   1188             mbedtls_ecdsa_free(&ecdsa);
   1189         }
   1190     }
   1191 #endif
   1192 
   1193 #if defined(MBEDTLS_ECDH_C)
   1194     if (todo.ecdh) {
   1195         mbedtls_ecdh_context ecdh_srv, ecdh_cli;
   1196         unsigned char buf_srv[BUFSIZE], buf_cli[BUFSIZE];
   1197         const mbedtls_ecp_curve_info *curve_info;
   1198         size_t params_len, publen, seclen;
   1199 
   1200         for (curve_info = curve_list;
   1201              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
   1202              curve_info++) {
   1203             if (!mbedtls_ecdh_can_do(curve_info->grp_id)) {
   1204                 continue;
   1205             }
   1206 
   1207             mbedtls_ecdh_init(&ecdh_srv);
   1208 
   1209             CHECK_AND_CONTINUE(mbedtls_ecdh_setup(&ecdh_srv, curve_info->grp_id));
   1210             CHECK_AND_CONTINUE(mbedtls_ecdh_make_params(&ecdh_srv, &params_len, buf_srv,
   1211                                                         sizeof(buf_srv), myrand, NULL));
   1212 
   1213             mbedtls_snprintf(title, sizeof(title), "ECDHE-%s", curve_info->name);
   1214             TIME_PUBLIC(title,
   1215                         "ephemeral handshake",
   1216                         const unsigned char *p_srv = buf_srv;
   1217                         mbedtls_ecdh_init(&ecdh_cli);
   1218 
   1219                         CHECK_AND_CONTINUE(mbedtls_ecdh_read_params(&ecdh_cli, &p_srv,
   1220                                                                     p_srv + params_len));
   1221                         CHECK_AND_CONTINUE(mbedtls_ecdh_make_public(&ecdh_cli, &publen, buf_cli,
   1222                                                                     sizeof(buf_cli), myrand, NULL));
   1223 
   1224                         CHECK_AND_CONTINUE(mbedtls_ecdh_calc_secret(&ecdh_cli, &seclen, buf_cli,
   1225                                                                     sizeof(buf_cli), myrand, NULL));
   1226                         mbedtls_ecdh_free(&ecdh_cli);
   1227                         );
   1228 
   1229             mbedtls_ecdh_free(&ecdh_srv);
   1230         }
   1231 
   1232         for (curve_info = curve_list;
   1233              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
   1234              curve_info++) {
   1235             if (!mbedtls_ecdh_can_do(curve_info->grp_id)) {
   1236                 continue;
   1237             }
   1238 
   1239             mbedtls_ecdh_init(&ecdh_srv);
   1240             mbedtls_ecdh_init(&ecdh_cli);
   1241 
   1242             CHECK_AND_CONTINUE(mbedtls_ecdh_setup(&ecdh_srv, curve_info->grp_id));
   1243             CHECK_AND_CONTINUE(mbedtls_ecdh_make_params(&ecdh_srv, &params_len, buf_srv,
   1244                                                         sizeof(buf_srv), myrand, NULL));
   1245 
   1246             const unsigned char *p_srv = buf_srv;
   1247             CHECK_AND_CONTINUE(mbedtls_ecdh_read_params(&ecdh_cli, &p_srv,
   1248                                                         p_srv + params_len));
   1249             CHECK_AND_CONTINUE(mbedtls_ecdh_make_public(&ecdh_cli, &publen, buf_cli,
   1250                                                         sizeof(buf_cli), myrand, NULL));
   1251 
   1252 
   1253             mbedtls_snprintf(title, sizeof(title), "ECDH-%s", curve_info->name);
   1254             TIME_PUBLIC(title,
   1255                         "static handshake",
   1256                         CHECK_AND_CONTINUE(mbedtls_ecdh_calc_secret(&ecdh_cli, &seclen, buf_cli,
   1257                                                                     sizeof(buf_cli), myrand, NULL));
   1258                         );
   1259 
   1260             mbedtls_ecdh_free(&ecdh_cli);
   1261             mbedtls_ecdh_free(&ecdh_srv);
   1262         }
   1263     }
   1264 #endif
   1265 
   1266     mbedtls_printf("\n");
   1267 
   1268 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
   1269     mbedtls_memory_buffer_alloc_free();
   1270 #endif
   1271 
   1272     mbedtls_exit(0);
   1273 }
   1274 
   1275 #endif /* MBEDTLS_HAVE_TIME */