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