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