1 /*
2  *  Benchmark demonstration program
3  *
4  *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: GPL-2.0
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  *  This file is part of mbed TLS (https://tls.mbed.org)
22  */
23 
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
26 #else
27 #include MBEDTLS_CONFIG_FILE
28 #endif
29 
30 #if defined(MBEDTLS_PLATFORM_C)
31 #include "mbedtls/platform.h"
32 #else
33 #include <stdio.h>
34 #define mbedtls_exit       exit
35 #define mbedtls_printf     printf
36 #define mbedtls_snprintf   snprintf
37 #define mbedtls_free       free
38 #endif
39 
40 #if !defined(MBEDTLS_TIMING_C)
main(void)41 int main( void )
42 {
43     mbedtls_printf("MBEDTLS_TIMING_C not defined.\n");
44     return( 0 );
45 }
46 #else
47 
48 #include <string.h>
49 #include <stdlib.h>
50 
51 #include "mbedtls/timing.h"
52 
53 #include "mbedtls/md4.h"
54 #include "mbedtls/md5.h"
55 #include "mbedtls/ripemd160.h"
56 #include "mbedtls/sha1.h"
57 #include "mbedtls/sha256.h"
58 #include "mbedtls/sha512.h"
59 
60 #include "mbedtls/arc4.h"
61 #include "mbedtls/des.h"
62 #include "mbedtls/aes.h"
63 #include "mbedtls/aria.h"
64 #include "mbedtls/blowfish.h"
65 #include "mbedtls/camellia.h"
66 #include "mbedtls/chacha20.h"
67 #include "mbedtls/gcm.h"
68 #include "mbedtls/ccm.h"
69 #include "mbedtls/chachapoly.h"
70 #include "mbedtls/cmac.h"
71 #include "mbedtls/poly1305.h"
72 
73 #include "mbedtls/havege.h"
74 #include "mbedtls/ctr_drbg.h"
75 #include "mbedtls/hmac_drbg.h"
76 
77 #include "mbedtls/rsa.h"
78 #include "mbedtls/dhm.h"
79 #include "mbedtls/ecdsa.h"
80 #include "mbedtls/ecdh.h"
81 
82 #include "mbedtls/error.h"
83 
84 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
85 #include "mbedtls/memory_buffer_alloc.h"
86 #endif
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     "md4, md5, ripemd160, sha1, sha256, sha512,\n"                      \
106     "arc4, des3, des, camellia, blowfish, chacha20,\n"                  \
107     "aes_cbc, aes_gcm, aes_ccm, aes_ctx, chachapoly,\n"                 \
108     "aes_cmac, des3_cmac, poly1305\n"                                   \
109     "havege, ctr_drbg, hmac_drbg\n"                                     \
110     "rsa, dhm, ecdsa, ecdh.\n"
111 
112 #if defined(MBEDTLS_ERROR_C)
113 #define PRINT_ERROR                                                     \
114         mbedtls_strerror( ret, ( char * )tmp, sizeof( tmp ) );          \
115         mbedtls_printf( "FAILED: %s\n", tmp );
116 #else
117 #define PRINT_ERROR                                                     \
118         mbedtls_printf( "FAILED: -0x%04x\n", -ret );
119 #endif
120 
121 #define TIME_AND_TSC( TITLE, CODE )                                     \
122 do {                                                                    \
123     unsigned long ii, jj, tsc;                                          \
124     int ret = 0;                                                        \
125                                                                         \
126     mbedtls_printf( HEADER_FORMAT, TITLE );                             \
127     fflush( stdout );                                                   \
128                                                                         \
129     mbedtls_set_alarm( 1 );                                             \
130     for( ii = 1; ret == 0 && ! mbedtls_timing_alarmed; ii++ )           \
131     {                                                                   \
132         ret = CODE;                                                     \
133     }                                                                   \
134                                                                         \
135     tsc = mbedtls_timing_hardclock();                                   \
136     for( jj = 0; ret == 0 && jj < 1024; jj++ )                          \
137     {                                                                   \
138         ret = CODE;                                                     \
139     }                                                                   \
140                                                                         \
141     if( ret != 0 )                                                      \
142     {                                                                   \
143         PRINT_ERROR;                                                    \
144     }                                                                   \
145     else                                                                \
146     {                                                                   \
147         mbedtls_printf( "%9lu KiB/s,  %9lu cycles/byte\n",              \
148                          ii * BUFSIZE / 1024,                           \
149                          ( mbedtls_timing_hardclock() - tsc )           \
150                          / ( jj * BUFSIZE ) );                          \
151     }                                                                   \
152 } while( 0 )
153 
154 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG)
155 
156 #define MEMORY_MEASURE_INIT                                             \
157     size_t max_used, max_blocks, max_bytes;                             \
158     size_t prv_used, prv_blocks;                                        \
159     mbedtls_memory_buffer_alloc_cur_get( &prv_used, &prv_blocks );      \
160     mbedtls_memory_buffer_alloc_max_reset( );
161 
162 #define MEMORY_MEASURE_PRINT( title_len )                               \
163     mbedtls_memory_buffer_alloc_max_get( &max_used, &max_blocks );      \
164     for( ii = 12 - title_len; ii != 0; ii-- ) mbedtls_printf( " " );    \
165     max_used -= prv_used;                                               \
166     max_blocks -= prv_blocks;                                           \
167     max_bytes = max_used + MEM_BLOCK_OVERHEAD * max_blocks;             \
168     mbedtls_printf( "%6u heap bytes", (unsigned) max_bytes );
169 
170 #else
171 #define MEMORY_MEASURE_INIT
172 #define MEMORY_MEASURE_PRINT( title_len )
173 #endif
174 
175 #define TIME_PUBLIC( TITLE, TYPE, CODE )                                \
176 do {                                                                    \
177     unsigned long ii;                                                   \
178     int ret;                                                            \
179     MEMORY_MEASURE_INIT;                                                \
180                                                                         \
181     mbedtls_printf( HEADER_FORMAT, TITLE );                             \
182     fflush( stdout );                                                   \
183     mbedtls_set_alarm( 3 );                                             \
184                                                                         \
185     ret = 0;                                                            \
186     for( ii = 1; ! mbedtls_timing_alarmed && ! ret ; ii++ )             \
187     {                                                                   \
188         CODE;                                                           \
189     }                                                                   \
190                                                                         \
191     if( ret != 0 )                                                      \
192     {                                                                   \
193         PRINT_ERROR;                                                    \
194     }                                                                   \
195     else                                                                \
196     {                                                                   \
197         mbedtls_printf( "%6lu " TYPE "/s", ii / 3 );                    \
198         MEMORY_MEASURE_PRINT( sizeof( TYPE ) + 1 );                     \
199         mbedtls_printf( "\n" );                                         \
200     }                                                                   \
201 } while( 0 )
202 
myrand(void * rng_state,unsigned char * output,size_t len)203 static int myrand( void *rng_state, unsigned char *output, size_t len )
204 {
205     size_t use_len;
206     int rnd;
207 
208     if( rng_state != NULL )
209         rng_state  = NULL;
210 
211     while( len > 0 )
212     {
213         use_len = len;
214         if( use_len > sizeof(int) )
215             use_len = sizeof(int);
216 
217         rnd = rand();
218         memcpy( output, &rnd, use_len );
219         output += use_len;
220         len -= use_len;
221     }
222 
223     return( 0 );
224 }
225 
226 /*
227  * Clear some memory that was used to prepare the context
228  */
229 #if defined(MBEDTLS_ECP_C)
ecp_clear_precomputed(mbedtls_ecp_group * grp)230 void ecp_clear_precomputed( mbedtls_ecp_group *grp )
231 {
232     if( grp->T != NULL )
233     {
234         size_t i;
235         for( i = 0; i < grp->T_size; i++ )
236             mbedtls_ecp_point_free( &grp->T[i] );
237         mbedtls_free( grp->T );
238     }
239     grp->T = NULL;
240     grp->T_size = 0;
241 }
242 #else
243 #define ecp_clear_precomputed( g )
244 #endif
245 
246 unsigned char buf[BUFSIZE];
247 
248 typedef struct {
249     char md4, md5, ripemd160, sha1, sha256, sha512,
250          arc4, des3, des,
251          aes_cbc, aes_gcm, aes_ccm, aes_xts, chachapoly,
252          aes_cmac, des3_cmac,
253          aria, camellia, blowfish, chacha20,
254          poly1305,
255          havege, ctr_drbg, hmac_drbg,
256          rsa, dhm, ecdsa, ecdh;
257 } todo_list;
258 
main(int argc,char * argv[])259 int main( int argc, char *argv[] )
260 {
261     int i;
262     unsigned char tmp[200];
263     char title[TITLE_LEN];
264     todo_list todo;
265 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
266     unsigned char alloc_buf[HEAP_SIZE] = { 0 };
267 #endif
268 
269     if( argc <= 1 )
270     {
271         memset( &todo, 1, sizeof( todo ) );
272     }
273     else
274     {
275         memset( &todo, 0, sizeof( todo ) );
276 
277         for( i = 1; i < argc; i++ )
278         {
279             if( strcmp( argv[i], "md4" ) == 0 )
280                 todo.md4 = 1;
281             else if( strcmp( argv[i], "md5" ) == 0 )
282                 todo.md5 = 1;
283             else if( strcmp( argv[i], "ripemd160" ) == 0 )
284                 todo.ripemd160 = 1;
285             else if( strcmp( argv[i], "sha1" ) == 0 )
286                 todo.sha1 = 1;
287             else if( strcmp( argv[i], "sha256" ) == 0 )
288                 todo.sha256 = 1;
289             else if( strcmp( argv[i], "sha512" ) == 0 )
290                 todo.sha512 = 1;
291             else if( strcmp( argv[i], "arc4" ) == 0 )
292                 todo.arc4 = 1;
293             else if( strcmp( argv[i], "des3" ) == 0 )
294                 todo.des3 = 1;
295             else if( strcmp( argv[i], "des" ) == 0 )
296                 todo.des = 1;
297             else if( strcmp( argv[i], "aes_cbc" ) == 0 )
298                 todo.aes_cbc = 1;
299             else if( strcmp( argv[i], "aes_xts" ) == 0 )
300                 todo.aes_xts = 1;
301             else if( strcmp( argv[i], "aes_gcm" ) == 0 )
302                 todo.aes_gcm = 1;
303             else if( strcmp( argv[i], "aes_ccm" ) == 0 )
304                 todo.aes_ccm = 1;
305             else if( strcmp( argv[i], "chachapoly" ) == 0 )
306                 todo.chachapoly = 1;
307             else if( strcmp( argv[i], "aes_cmac" ) == 0 )
308                 todo.aes_cmac = 1;
309             else if( strcmp( argv[i], "des3_cmac" ) == 0 )
310                 todo.des3_cmac = 1;
311             else if( strcmp( argv[i], "aria" ) == 0 )
312                 todo.aria = 1;
313             else if( strcmp( argv[i], "camellia" ) == 0 )
314                 todo.camellia = 1;
315             else if( strcmp( argv[i], "blowfish" ) == 0 )
316                 todo.blowfish = 1;
317             else if( strcmp( argv[i], "chacha20" ) == 0 )
318                 todo.chacha20 = 1;
319             else if( strcmp( argv[i], "poly1305" ) == 0 )
320                 todo.poly1305 = 1;
321             else if( strcmp( argv[i], "havege" ) == 0 )
322                 todo.havege = 1;
323             else if( strcmp( argv[i], "ctr_drbg" ) == 0 )
324                 todo.ctr_drbg = 1;
325             else if( strcmp( argv[i], "hmac_drbg" ) == 0 )
326                 todo.hmac_drbg = 1;
327             else if( strcmp( argv[i], "rsa" ) == 0 )
328                 todo.rsa = 1;
329             else if( strcmp( argv[i], "dhm" ) == 0 )
330                 todo.dhm = 1;
331             else if( strcmp( argv[i], "ecdsa" ) == 0 )
332                 todo.ecdsa = 1;
333             else if( strcmp( argv[i], "ecdh" ) == 0 )
334                 todo.ecdh = 1;
335             else
336             {
337                 mbedtls_printf( "Unrecognized option: %s\n", argv[i] );
338                 mbedtls_printf( "Available options: " OPTIONS );
339             }
340         }
341     }
342 
343     mbedtls_printf( "\n" );
344 
345 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
346     mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
347 #endif
348     memset( buf, 0xAA, sizeof( buf ) );
349     memset( tmp, 0xBB, sizeof( tmp ) );
350 
351 #if defined(MBEDTLS_MD4_C)
352     if( todo.md4 )
353         TIME_AND_TSC( "MD4", mbedtls_md4_ret( buf, BUFSIZE, tmp ) );
354 #endif
355 
356 #if defined(MBEDTLS_MD5_C)
357     if( todo.md5 )
358         TIME_AND_TSC( "MD5", mbedtls_md5_ret( buf, BUFSIZE, tmp ) );
359 #endif
360 
361 #if defined(MBEDTLS_RIPEMD160_C)
362     if( todo.ripemd160 )
363         TIME_AND_TSC( "RIPEMD160", mbedtls_ripemd160_ret( buf, BUFSIZE, tmp ) );
364 #endif
365 
366 #if defined(MBEDTLS_SHA1_C)
367     if( todo.sha1 )
368         TIME_AND_TSC( "SHA-1", mbedtls_sha1_ret( buf, BUFSIZE, tmp ) );
369 #endif
370 
371 #if defined(MBEDTLS_SHA256_C)
372     if( todo.sha256 )
373         TIME_AND_TSC( "SHA-256", mbedtls_sha256_ret( buf, BUFSIZE, tmp, 0 ) );
374 #endif
375 
376 #if defined(MBEDTLS_SHA512_C)
377     if( todo.sha512 )
378         TIME_AND_TSC( "SHA-512", mbedtls_sha512_ret( buf, BUFSIZE, tmp, 0 ) );
379 #endif
380 
381 #if defined(MBEDTLS_ARC4_C)
382     if( todo.arc4 )
383     {
384         mbedtls_arc4_context arc4;
385         mbedtls_arc4_init( &arc4 );
386         mbedtls_arc4_setup( &arc4, tmp, 32 );
387         TIME_AND_TSC( "ARC4", mbedtls_arc4_crypt( &arc4, BUFSIZE, buf, buf ) );
388         mbedtls_arc4_free( &arc4 );
389     }
390 #endif
391 
392 #if defined(MBEDTLS_DES_C)
393 #if defined(MBEDTLS_CIPHER_MODE_CBC)
394     if( todo.des3 )
395     {
396         mbedtls_des3_context des3;
397         mbedtls_des3_init( &des3 );
398         mbedtls_des3_set3key_enc( &des3, tmp );
399         TIME_AND_TSC( "3DES",
400                 mbedtls_des3_crypt_cbc( &des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
401         mbedtls_des3_free( &des3 );
402     }
403 
404     if( todo.des )
405     {
406         mbedtls_des_context des;
407         mbedtls_des_init( &des );
408         mbedtls_des_setkey_enc( &des, tmp );
409         TIME_AND_TSC( "DES",
410                 mbedtls_des_crypt_cbc( &des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
411         mbedtls_des_free( &des );
412     }
413 
414 #endif /* MBEDTLS_CIPHER_MODE_CBC */
415 #if defined(MBEDTLS_CMAC_C)
416     if( todo.des3_cmac )
417     {
418         unsigned char output[8];
419         const mbedtls_cipher_info_t *cipher_info;
420 
421         memset( buf, 0, sizeof( buf ) );
422         memset( tmp, 0, sizeof( tmp ) );
423 
424         cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_DES_EDE3_ECB );
425 
426         TIME_AND_TSC( "3DES-CMAC",
427                       mbedtls_cipher_cmac( cipher_info, tmp, 192, buf,
428                       BUFSIZE, output ) );
429     }
430 #endif /* MBEDTLS_CMAC_C */
431 #endif /* MBEDTLS_DES_C */
432 
433 #if defined(MBEDTLS_AES_C)
434 #if defined(MBEDTLS_CIPHER_MODE_CBC)
435     if( todo.aes_cbc )
436     {
437         int keysize;
438         mbedtls_aes_context aes;
439         mbedtls_aes_init( &aes );
440         for( keysize = 128; keysize <= 256; keysize += 64 )
441         {
442             mbedtls_snprintf( title, sizeof( title ), "AES-CBC-%d", keysize );
443 
444             memset( buf, 0, sizeof( buf ) );
445             memset( tmp, 0, sizeof( tmp ) );
446             mbedtls_aes_setkey_enc( &aes, tmp, keysize );
447 
448             TIME_AND_TSC( title,
449                 mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
450         }
451         mbedtls_aes_free( &aes );
452     }
453 #endif
454 #if defined(MBEDTLS_CIPHER_MODE_XTS)
455     if( todo.aes_xts )
456     {
457         int keysize;
458         mbedtls_aes_xts_context ctx;
459 
460         mbedtls_aes_xts_init( &ctx );
461         for( keysize = 128; keysize <= 256; keysize += 128 )
462         {
463             mbedtls_snprintf( title, sizeof( title ), "AES-XTS-%d", keysize );
464 
465             memset( buf, 0, sizeof( buf ) );
466             memset( tmp, 0, sizeof( tmp ) );
467             mbedtls_aes_xts_setkey_enc( &ctx, tmp, keysize * 2 );
468 
469             TIME_AND_TSC( title,
470                     mbedtls_aes_crypt_xts( &ctx, MBEDTLS_AES_ENCRYPT, BUFSIZE,
471                                            tmp, buf, buf ) );
472 
473             mbedtls_aes_xts_free( &ctx );
474         }
475     }
476 #endif
477 #if defined(MBEDTLS_GCM_C)
478     if( todo.aes_gcm )
479     {
480         int keysize;
481         mbedtls_gcm_context gcm;
482 
483         mbedtls_gcm_init( &gcm );
484         for( keysize = 128; keysize <= 256; keysize += 64 )
485         {
486             mbedtls_snprintf( title, sizeof( title ), "AES-GCM-%d", keysize );
487 
488             memset( buf, 0, sizeof( buf ) );
489             memset( tmp, 0, sizeof( tmp ) );
490             mbedtls_gcm_setkey( &gcm, MBEDTLS_CIPHER_ID_AES, tmp, keysize );
491 
492             TIME_AND_TSC( title,
493                     mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT, BUFSIZE, tmp,
494                         12, NULL, 0, buf, buf, 16, tmp ) );
495 
496             mbedtls_gcm_free( &gcm );
497         }
498     }
499 #endif
500 #if defined(MBEDTLS_CCM_C)
501     if( todo.aes_ccm )
502     {
503         int keysize;
504         mbedtls_ccm_context ccm;
505 
506         mbedtls_ccm_init( &ccm );
507         for( keysize = 128; keysize <= 256; keysize += 64 )
508         {
509             mbedtls_snprintf( title, sizeof( title ), "AES-CCM-%d", keysize );
510 
511             memset( buf, 0, sizeof( buf ) );
512             memset( tmp, 0, sizeof( tmp ) );
513             mbedtls_ccm_setkey( &ccm, MBEDTLS_CIPHER_ID_AES, tmp, keysize );
514 
515             TIME_AND_TSC( title,
516                     mbedtls_ccm_encrypt_and_tag( &ccm, BUFSIZE, tmp,
517                         12, NULL, 0, buf, buf, tmp, 16 ) );
518 
519             mbedtls_ccm_free( &ccm );
520         }
521     }
522 #endif
523 #if defined(MBEDTLS_CHACHAPOLY_C)
524     if( todo.chachapoly )
525     {
526         mbedtls_chachapoly_context chachapoly;
527 
528         mbedtls_chachapoly_init( &chachapoly );
529         memset( buf, 0, sizeof( buf ) );
530         memset( tmp, 0, sizeof( tmp ) );
531 
532         mbedtls_snprintf( title, sizeof( title ), "ChaCha20-Poly1305" );
533 
534         mbedtls_chachapoly_setkey( &chachapoly, tmp );
535 
536         TIME_AND_TSC( title,
537                 mbedtls_chachapoly_encrypt_and_tag( &chachapoly,
538                     BUFSIZE, tmp, NULL, 0, buf, buf, tmp ) );
539 
540         mbedtls_chachapoly_free( &chachapoly );
541     }
542 #endif
543 #if defined(MBEDTLS_CMAC_C)
544     if( todo.aes_cmac )
545     {
546         unsigned char output[16];
547         const mbedtls_cipher_info_t *cipher_info;
548         mbedtls_cipher_type_t cipher_type;
549         int keysize;
550 
551         for( keysize = 128, cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
552              keysize <= 256;
553              keysize += 64, cipher_type++ )
554         {
555             mbedtls_snprintf( title, sizeof( title ), "AES-CMAC-%d", keysize );
556 
557             memset( buf, 0, sizeof( buf ) );
558             memset( tmp, 0, sizeof( tmp ) );
559 
560             cipher_info = mbedtls_cipher_info_from_type( cipher_type );
561 
562             TIME_AND_TSC( title,
563                           mbedtls_cipher_cmac( cipher_info, tmp, keysize,
564                                                buf, BUFSIZE, output ) );
565         }
566 
567         memset( buf, 0, sizeof( buf ) );
568         memset( tmp, 0, sizeof( tmp ) );
569         TIME_AND_TSC( "AES-CMAC-PRF-128",
570                       mbedtls_aes_cmac_prf_128( tmp, 16, buf, BUFSIZE,
571                                                 output ) );
572     }
573 #endif /* MBEDTLS_CMAC_C */
574 #endif /* MBEDTLS_AES_C */
575 
576 #if defined(MBEDTLS_ARIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
577     if( todo.aria )
578     {
579         int keysize;
580         mbedtls_aria_context aria;
581         mbedtls_aria_init( &aria );
582         for( keysize = 128; keysize <= 256; keysize += 64 )
583         {
584             mbedtls_snprintf( title, sizeof( title ), "ARIA-CBC-%d", keysize );
585 
586             memset( buf, 0, sizeof( buf ) );
587             memset( tmp, 0, sizeof( tmp ) );
588             mbedtls_aria_setkey_enc( &aria, tmp, keysize );
589 
590             TIME_AND_TSC( title,
591                     mbedtls_aria_crypt_cbc( &aria, MBEDTLS_ARIA_ENCRYPT,
592                         BUFSIZE, tmp, buf, buf ) );
593         }
594         mbedtls_aria_free( &aria );
595     }
596 #endif
597 
598 #if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
599     if( todo.camellia )
600     {
601         int keysize;
602         mbedtls_camellia_context camellia;
603         mbedtls_camellia_init( &camellia );
604         for( keysize = 128; keysize <= 256; keysize += 64 )
605         {
606             mbedtls_snprintf( title, sizeof( title ), "CAMELLIA-CBC-%d", keysize );
607 
608             memset( buf, 0, sizeof( buf ) );
609             memset( tmp, 0, sizeof( tmp ) );
610             mbedtls_camellia_setkey_enc( &camellia, tmp, keysize );
611 
612             TIME_AND_TSC( title,
613                     mbedtls_camellia_crypt_cbc( &camellia, MBEDTLS_CAMELLIA_ENCRYPT,
614                         BUFSIZE, tmp, buf, buf ) );
615         }
616         mbedtls_camellia_free( &camellia );
617     }
618 #endif
619 
620 #if defined(MBEDTLS_CHACHA20_C)
621     if ( todo.chacha20 )
622     {
623         TIME_AND_TSC( "ChaCha20", mbedtls_chacha20_crypt( buf, buf, 0U, BUFSIZE, buf, buf ) );
624     }
625 #endif
626 
627 #if defined(MBEDTLS_POLY1305_C)
628     if ( todo.poly1305 )
629     {
630         TIME_AND_TSC( "Poly1305", mbedtls_poly1305_mac( buf, buf, BUFSIZE, buf ) );
631     }
632 #endif
633 
634 #if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
635     if( todo.blowfish )
636     {
637         int keysize;
638         mbedtls_blowfish_context blowfish;
639         mbedtls_blowfish_init( &blowfish );
640 
641         for( keysize = 128; keysize <= 256; keysize += 64 )
642         {
643             mbedtls_snprintf( title, sizeof( title ), "BLOWFISH-CBC-%d", keysize );
644 
645             memset( buf, 0, sizeof( buf ) );
646             memset( tmp, 0, sizeof( tmp ) );
647             mbedtls_blowfish_setkey( &blowfish, tmp, keysize );
648 
649             TIME_AND_TSC( title,
650                     mbedtls_blowfish_crypt_cbc( &blowfish, MBEDTLS_BLOWFISH_ENCRYPT, BUFSIZE,
651                         tmp, buf, buf ) );
652         }
653 
654         mbedtls_blowfish_free( &blowfish );
655     }
656 #endif
657 
658 #if defined(MBEDTLS_HAVEGE_C)
659     if( todo.havege )
660     {
661         mbedtls_havege_state hs;
662         mbedtls_havege_init( &hs );
663         TIME_AND_TSC( "HAVEGE", mbedtls_havege_random( &hs, buf, BUFSIZE ) );
664         mbedtls_havege_free( &hs );
665     }
666 #endif
667 
668 #if defined(MBEDTLS_CTR_DRBG_C)
669     if( todo.ctr_drbg )
670     {
671         mbedtls_ctr_drbg_context ctr_drbg;
672 
673         mbedtls_ctr_drbg_init( &ctr_drbg );
674 
675         if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
676             mbedtls_exit(1);
677         TIME_AND_TSC( "CTR_DRBG (NOPR)",
678                 mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) );
679 
680         if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
681             mbedtls_exit(1);
682         mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );
683         TIME_AND_TSC( "CTR_DRBG (PR)",
684                 mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) );
685         mbedtls_ctr_drbg_free( &ctr_drbg );
686     }
687 #endif
688 
689 #if defined(MBEDTLS_HMAC_DRBG_C)
690     if( todo.hmac_drbg )
691     {
692         mbedtls_hmac_drbg_context hmac_drbg;
693         const mbedtls_md_info_t *md_info;
694 
695         mbedtls_hmac_drbg_init( &hmac_drbg );
696 
697 #if defined(MBEDTLS_SHA1_C)
698         if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL )
699             mbedtls_exit(1);
700 
701         if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
702             mbedtls_exit(1);
703         TIME_AND_TSC( "HMAC_DRBG SHA-1 (NOPR)",
704                 mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
705         mbedtls_hmac_drbg_free( &hmac_drbg );
706 
707         if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
708             mbedtls_exit(1);
709         mbedtls_hmac_drbg_set_prediction_resistance( &hmac_drbg,
710                                              MBEDTLS_HMAC_DRBG_PR_ON );
711         TIME_AND_TSC( "HMAC_DRBG SHA-1 (PR)",
712                 mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
713         mbedtls_hmac_drbg_free( &hmac_drbg );
714 #endif
715 
716 #if defined(MBEDTLS_SHA256_C)
717         if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ) ) == NULL )
718             mbedtls_exit(1);
719 
720         if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
721             mbedtls_exit(1);
722         TIME_AND_TSC( "HMAC_DRBG SHA-256 (NOPR)",
723                 mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
724         mbedtls_hmac_drbg_free( &hmac_drbg );
725 
726         if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
727             mbedtls_exit(1);
728         mbedtls_hmac_drbg_set_prediction_resistance( &hmac_drbg,
729                                              MBEDTLS_HMAC_DRBG_PR_ON );
730         TIME_AND_TSC( "HMAC_DRBG SHA-256 (PR)",
731                 mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) );
732         mbedtls_hmac_drbg_free( &hmac_drbg );
733 #endif
734     }
735 #endif
736 
737 #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
738     if( todo.rsa )
739     {
740         int keysize;
741         mbedtls_rsa_context rsa;
742         for( keysize = 2048; keysize <= 4096; keysize *= 2 )
743         {
744             mbedtls_snprintf( title, sizeof( title ), "RSA-%d", keysize );
745 
746             mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
747             mbedtls_rsa_gen_key( &rsa, myrand, NULL, keysize, 65537 );
748 
749             TIME_PUBLIC( title, " public",
750                     buf[0] = 0;
751                     ret = mbedtls_rsa_public( &rsa, buf, buf ) );
752 
753             TIME_PUBLIC( title, "private",
754                     buf[0] = 0;
755                     ret = mbedtls_rsa_private( &rsa, myrand, NULL, buf, buf ) );
756 
757             mbedtls_rsa_free( &rsa );
758         }
759     }
760 #endif
761 
762 #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_BIGNUM_C)
763     if( todo.dhm )
764     {
765         int dhm_sizes[] = { 2048, 3072 };
766         static const unsigned char dhm_P_2048[] =
767             MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN;
768         static const unsigned char dhm_P_3072[] =
769             MBEDTLS_DHM_RFC3526_MODP_3072_P_BIN;
770         static const unsigned char dhm_G_2048[] =
771             MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN;
772         static const unsigned char dhm_G_3072[] =
773             MBEDTLS_DHM_RFC3526_MODP_3072_G_BIN;
774 
775         const unsigned char *dhm_P[] = { dhm_P_2048, dhm_P_3072 };
776         const size_t dhm_P_size[] = { sizeof( dhm_P_2048 ),
777                                       sizeof( dhm_P_3072 ) };
778 
779         const unsigned char *dhm_G[] = { dhm_G_2048, dhm_G_3072 };
780         const size_t dhm_G_size[] = { sizeof( dhm_G_2048 ),
781                                       sizeof( dhm_G_3072 ) };
782 
783         mbedtls_dhm_context dhm;
784         size_t olen;
785         for( i = 0; (size_t) i < sizeof( dhm_sizes ) / sizeof( dhm_sizes[0] ); i++ )
786         {
787             mbedtls_dhm_init( &dhm );
788 
789             if( mbedtls_mpi_read_binary( &dhm.P, dhm_P[i],
790                                          dhm_P_size[i] ) != 0 ||
791                 mbedtls_mpi_read_binary( &dhm.G, dhm_G[i],
792                                          dhm_G_size[i] ) != 0 )
793             {
794                 mbedtls_exit( 1 );
795             }
796 
797             dhm.len = mbedtls_mpi_size( &dhm.P );
798             mbedtls_dhm_make_public( &dhm, (int) dhm.len, buf, dhm.len, myrand, NULL );
799             if( mbedtls_mpi_copy( &dhm.GY, &dhm.GX ) != 0 )
800                 mbedtls_exit( 1 );
801 
802             mbedtls_snprintf( title, sizeof( title ), "DHE-%d", dhm_sizes[i] );
803             TIME_PUBLIC( title, "handshake",
804                     ret |= mbedtls_dhm_make_public( &dhm, (int) dhm.len, buf, dhm.len,
805                                             myrand, NULL );
806                     ret |= mbedtls_dhm_calc_secret( &dhm, buf, sizeof( buf ), &olen, myrand, NULL ) );
807 
808             mbedtls_snprintf( title, sizeof( title ), "DH-%d", dhm_sizes[i] );
809             TIME_PUBLIC( title, "handshake",
810                     ret |= mbedtls_dhm_calc_secret( &dhm, buf, sizeof( buf ), &olen, myrand, NULL ) );
811 
812             mbedtls_dhm_free( &dhm );
813         }
814     }
815 #endif
816 
817 #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA256_C)
818     if( todo.ecdsa )
819     {
820         mbedtls_ecdsa_context ecdsa;
821         const mbedtls_ecp_curve_info *curve_info;
822         size_t sig_len;
823 
824         memset( buf, 0x2A, sizeof( buf ) );
825 
826         for( curve_info = mbedtls_ecp_curve_list();
827              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
828              curve_info++ )
829         {
830             mbedtls_ecdsa_init( &ecdsa );
831 
832             if( mbedtls_ecdsa_genkey( &ecdsa, curve_info->grp_id, myrand, NULL ) != 0 )
833                 mbedtls_exit( 1 );
834             ecp_clear_precomputed( &ecdsa.grp );
835 
836             mbedtls_snprintf( title, sizeof( title ), "ECDSA-%s",
837                                               curve_info->name );
838             TIME_PUBLIC( title, "sign",
839                     ret = mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
840                                                 tmp, &sig_len, myrand, NULL ) );
841 
842             mbedtls_ecdsa_free( &ecdsa );
843         }
844 
845         for( curve_info = mbedtls_ecp_curve_list();
846              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
847              curve_info++ )
848         {
849             mbedtls_ecdsa_init( &ecdsa );
850 
851             if( mbedtls_ecdsa_genkey( &ecdsa, curve_info->grp_id, myrand, NULL ) != 0 ||
852                 mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
853                                                tmp, &sig_len, myrand, NULL ) != 0 )
854             {
855                 mbedtls_exit( 1 );
856             }
857             ecp_clear_precomputed( &ecdsa.grp );
858 
859             mbedtls_snprintf( title, sizeof( title ), "ECDSA-%s",
860                                               curve_info->name );
861             TIME_PUBLIC( title, "verify",
862                     ret = mbedtls_ecdsa_read_signature( &ecdsa, buf, curve_info->bit_size,
863                                                 tmp, sig_len ) );
864 
865             mbedtls_ecdsa_free( &ecdsa );
866         }
867     }
868 #endif
869 
870 #if defined(MBEDTLS_ECDH_C)
871     if( todo.ecdh )
872     {
873         mbedtls_ecdh_context ecdh;
874         mbedtls_mpi z;
875         const mbedtls_ecp_curve_info montgomery_curve_list[] = {
876 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
877             { MBEDTLS_ECP_DP_CURVE25519, 0, 0, "Curve25519" },
878 #endif
879 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
880             { MBEDTLS_ECP_DP_CURVE448, 0, 0, "Curve448" },
881 #endif
882             { MBEDTLS_ECP_DP_NONE, 0, 0, 0 }
883         };
884         const mbedtls_ecp_curve_info *curve_info;
885         size_t olen;
886 
887         for( curve_info = mbedtls_ecp_curve_list();
888              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
889              curve_info++ )
890         {
891             mbedtls_ecdh_init( &ecdh );
892 
893             if( mbedtls_ecp_group_load( &ecdh.grp, curve_info->grp_id ) != 0 ||
894                 mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
895                                   myrand, NULL ) != 0 ||
896                 mbedtls_ecp_copy( &ecdh.Qp, &ecdh.Q ) != 0 )
897             {
898                 mbedtls_exit( 1 );
899             }
900             ecp_clear_precomputed( &ecdh.grp );
901 
902             mbedtls_snprintf( title, sizeof( title ), "ECDHE-%s",
903                                               curve_info->name );
904             TIME_PUBLIC( title, "handshake",
905                     ret |= mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
906                                              myrand, NULL );
907                     ret |= mbedtls_ecdh_calc_secret( &ecdh, &olen, buf, sizeof( buf ),
908                                              myrand, NULL ) );
909             mbedtls_ecdh_free( &ecdh );
910         }
911 
912         /* Montgomery curves need to be handled separately */
913         for ( curve_info = montgomery_curve_list;
914               curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
915               curve_info++ )
916         {
917             mbedtls_ecdh_init( &ecdh );
918             mbedtls_mpi_init( &z );
919 
920             if( mbedtls_ecp_group_load( &ecdh.grp, curve_info->grp_id ) != 0 ||
921                 mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Qp, myrand, NULL ) != 0 )
922             {
923                 mbedtls_exit( 1 );
924             }
925 
926             mbedtls_snprintf( title, sizeof(title), "ECDHE-%s",
927                               curve_info->name );
928             TIME_PUBLIC(  title, "handshake",
929                     ret |= mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Q,
930                                             myrand, NULL );
931                     ret |= mbedtls_ecdh_compute_shared( &ecdh.grp, &z, &ecdh.Qp, &ecdh.d,
932                                                 myrand, NULL ) );
933 
934             mbedtls_ecdh_free( &ecdh );
935             mbedtls_mpi_free( &z );
936         }
937 
938         for( curve_info = mbedtls_ecp_curve_list();
939              curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
940              curve_info++ )
941         {
942             mbedtls_ecdh_init( &ecdh );
943 
944             if( mbedtls_ecp_group_load( &ecdh.grp, curve_info->grp_id ) != 0 ||
945                 mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
946                                   myrand, NULL ) != 0 ||
947                 mbedtls_ecp_copy( &ecdh.Qp, &ecdh.Q ) != 0 ||
948                 mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
949                                   myrand, NULL ) != 0 )
950             {
951                 mbedtls_exit( 1 );
952             }
953             ecp_clear_precomputed( &ecdh.grp );
954 
955             mbedtls_snprintf( title, sizeof( title ), "ECDH-%s",
956                                               curve_info->name );
957             TIME_PUBLIC( title, "handshake",
958                     ret |= mbedtls_ecdh_calc_secret( &ecdh, &olen, buf, sizeof( buf ),
959                                              myrand, NULL ) );
960             mbedtls_ecdh_free( &ecdh );
961         }
962 
963         /* Montgomery curves need to be handled separately */
964         for ( curve_info = montgomery_curve_list;
965               curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
966               curve_info++)
967         {
968             mbedtls_ecdh_init( &ecdh );
969             mbedtls_mpi_init( &z );
970 
971             if( mbedtls_ecp_group_load( &ecdh.grp, curve_info->grp_id ) != 0 ||
972                 mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Qp,
973                                  myrand, NULL ) != 0 ||
974                 mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Q, myrand, NULL ) != 0 )
975             {
976                 mbedtls_exit( 1 );
977             }
978 
979             mbedtls_snprintf( title, sizeof(title), "ECDH-%s",
980                               curve_info->name );
981             TIME_PUBLIC(  title, "handshake",
982                     ret |= mbedtls_ecdh_compute_shared( &ecdh.grp, &z, &ecdh.Qp, &ecdh.d,
983                                                 myrand, NULL ) );
984 
985             mbedtls_ecdh_free( &ecdh );
986             mbedtls_mpi_free( &z );
987         }
988     }
989 #endif
990 
991     mbedtls_printf( "\n" );
992 
993 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
994     mbedtls_memory_buffer_alloc_free();
995 #endif
996 
997 #if defined(_WIN32)
998     mbedtls_printf( "  Press Enter to exit this program.\n" );
999     fflush( stdout ); getchar();
1000 #endif
1001 
1002     return( 0 );
1003 }
1004 
1005 #endif /* MBEDTLS_TIMING_C */
1006