benchmark.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. /*
  2. * Benchmark demonstration program
  3. *
  4. * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * This file is part of mbed TLS (https://tls.mbed.org)
  20. */
  21. #if !defined(MBEDTLS_CONFIG_FILE)
  22. #include "mbedtls/config.h"
  23. #else
  24. #include MBEDTLS_CONFIG_FILE
  25. #endif
  26. #if defined(MBEDTLS_PLATFORM_C)
  27. #include "mbedtls/platform.h"
  28. #else
  29. #include <stdio.h>
  30. #define mbedtls_exit exit
  31. #define mbedtls_printf printf
  32. #define mbedtls_snprintf snprintf
  33. #define mbedtls_free free
  34. #endif
  35. #if !defined(MBEDTLS_TIMING_C)
  36. int main( void )
  37. {
  38. mbedtls_printf("MBEDTLS_TIMING_C not defined.\n");
  39. return( 0 );
  40. }
  41. #else
  42. #include <string.h>
  43. #include <stdlib.h>
  44. #include "mbedtls/timing.h"
  45. #include "mbedtls/md4.h"
  46. #include "mbedtls/md5.h"
  47. #include "mbedtls/ripemd160.h"
  48. #include "mbedtls/sha1.h"
  49. #include "mbedtls/sha256.h"
  50. #include "mbedtls/sha512.h"
  51. #include "mbedtls/arc4.h"
  52. #include "mbedtls/des.h"
  53. #include "mbedtls/aes.h"
  54. #include "mbedtls/blowfish.h"
  55. #include "mbedtls/camellia.h"
  56. #include "mbedtls/gcm.h"
  57. #include "mbedtls/ccm.h"
  58. #include "mbedtls/cmac.h"
  59. #include "mbedtls/havege.h"
  60. #include "mbedtls/ctr_drbg.h"
  61. #include "mbedtls/hmac_drbg.h"
  62. #include "mbedtls/rsa.h"
  63. #include "mbedtls/dhm.h"
  64. #include "mbedtls/ecdsa.h"
  65. #include "mbedtls/ecdh.h"
  66. #include "mbedtls/error.h"
  67. #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
  68. #include "mbedtls/memory_buffer_alloc.h"
  69. #endif
  70. /*
  71. * For heap usage estimates, we need an estimate of the overhead per allocated
  72. * block. ptmalloc2/3 (used in gnu libc for instance) uses 2 size_t per block,
  73. * so use that as our baseline.
  74. */
  75. #define MEM_BLOCK_OVERHEAD ( 2 * sizeof( size_t ) )
  76. /*
  77. * Size to use for the alloc buffer if MEMORY_BUFFER_ALLOC_C is defined.
  78. */
  79. #define HEAP_SIZE (1u << 16) // 64k
  80. #define BUFSIZE 1024
  81. #define HEADER_FORMAT " %-24s : "
  82. #define TITLE_LEN 25
  83. #define OPTIONS \
  84. "md4, md5, ripemd160, sha1, sha256, sha512,\n" \
  85. "arc4, des3, des, camellia, blowfish,\n" \
  86. "aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,\n" \
  87. "havege, ctr_drbg, hmac_drbg\n" \
  88. "rsa, dhm, ecdsa, ecdh.\n"
  89. #if defined(MBEDTLS_ERROR_C)
  90. #define PRINT_ERROR \
  91. mbedtls_strerror( ret, ( char * )tmp, sizeof( tmp ) ); \
  92. mbedtls_printf( "FAILED: %s\n", tmp );
  93. #else
  94. #define PRINT_ERROR \
  95. mbedtls_printf( "FAILED: -0x%04x\n", -ret );
  96. #endif
  97. #define TIME_AND_TSC( TITLE, CODE ) \
  98. do { \
  99. unsigned long ii, jj, tsc; \
  100. \
  101. mbedtls_printf( HEADER_FORMAT, TITLE ); \
  102. fflush( stdout ); \
  103. \
  104. mbedtls_set_alarm( 1 ); \
  105. for( ii = 1; ! mbedtls_timing_alarmed; ii++ ) \
  106. { \
  107. CODE; \
  108. } \
  109. \
  110. tsc = mbedtls_timing_hardclock(); \
  111. for( jj = 0; jj < 1024; jj++ ) \
  112. { \
  113. CODE; \
  114. } \
  115. \
  116. mbedtls_printf( "%9lu Kb/s, %9lu cycles/byte\n", \
  117. ii * BUFSIZE / 1024, \
  118. ( mbedtls_timing_hardclock() - tsc ) / ( jj * BUFSIZE ) ); \
  119. } while( 0 )
  120. #if defined(MBEDTLS_ERROR_C)
  121. #define PRINT_ERROR \
  122. mbedtls_strerror( ret, ( char * )tmp, sizeof( tmp ) ); \
  123. mbedtls_printf( "FAILED: %s\n", tmp );
  124. #else
  125. #define PRINT_ERROR \
  126. mbedtls_printf( "FAILED: -0x%04x\n", -ret );
  127. #endif
  128. #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG)
  129. #define MEMORY_MEASURE_INIT \
  130. size_t max_used, max_blocks, max_bytes; \
  131. size_t prv_used, prv_blocks; \
  132. mbedtls_memory_buffer_alloc_cur_get( &prv_used, &prv_blocks ); \
  133. mbedtls_memory_buffer_alloc_max_reset( );
  134. #define MEMORY_MEASURE_PRINT( title_len ) \
  135. mbedtls_memory_buffer_alloc_max_get( &max_used, &max_blocks ); \
  136. for( ii = 12 - title_len; ii != 0; ii-- ) mbedtls_printf( " " ); \
  137. max_used -= prv_used; \
  138. max_blocks -= prv_blocks; \
  139. max_bytes = max_used + MEM_BLOCK_OVERHEAD * max_blocks; \
  140. mbedtls_printf( "%6u heap bytes", (unsigned) max_bytes );
  141. #else
  142. #define MEMORY_MEASURE_INIT
  143. #define MEMORY_MEASURE_PRINT( title_len )
  144. #endif
  145. #define TIME_PUBLIC( TITLE, TYPE, CODE ) \
  146. do { \
  147. unsigned long ii; \
  148. int ret; \
  149. MEMORY_MEASURE_INIT; \
  150. \
  151. mbedtls_printf( HEADER_FORMAT, TITLE ); \
  152. fflush( stdout ); \
  153. mbedtls_set_alarm( 3 ); \
  154. \
  155. ret = 0; \
  156. for( ii = 1; ! mbedtls_timing_alarmed && ! ret ; ii++ ) \
  157. { \
  158. CODE; \
  159. } \
  160. \
  161. if( ret != 0 ) \
  162. { \
  163. PRINT_ERROR; \
  164. } \
  165. else \
  166. { \
  167. mbedtls_printf( "%6lu " TYPE "/s", ii / 3 ); \
  168. MEMORY_MEASURE_PRINT( sizeof( TYPE ) + 1 ); \
  169. mbedtls_printf( "\n" ); \
  170. } \
  171. } while( 0 )
  172. static int myrand( void *rng_state, unsigned char *output, size_t len )
  173. {
  174. size_t use_len;
  175. int rnd;
  176. if( rng_state != NULL )
  177. rng_state = NULL;
  178. while( len > 0 )
  179. {
  180. use_len = len;
  181. if( use_len > sizeof(int) )
  182. use_len = sizeof(int);
  183. rnd = rand();
  184. memcpy( output, &rnd, use_len );
  185. output += use_len;
  186. len -= use_len;
  187. }
  188. return( 0 );
  189. }
  190. /*
  191. * Clear some memory that was used to prepare the context
  192. */
  193. #if defined(MBEDTLS_ECP_C)
  194. void ecp_clear_precomputed( mbedtls_ecp_group *grp )
  195. {
  196. if( grp->T != NULL )
  197. {
  198. size_t i;
  199. for( i = 0; i < grp->T_size; i++ )
  200. mbedtls_ecp_point_free( &grp->T[i] );
  201. mbedtls_free( grp->T );
  202. }
  203. grp->T = NULL;
  204. grp->T_size = 0;
  205. }
  206. #else
  207. #define ecp_clear_precomputed( g )
  208. #endif
  209. unsigned char buf[BUFSIZE];
  210. typedef struct {
  211. char md4, md5, ripemd160, sha1, sha256, sha512,
  212. arc4, des3, des,
  213. aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,
  214. camellia, blowfish,
  215. havege, ctr_drbg, hmac_drbg,
  216. rsa, dhm, ecdsa, ecdh;
  217. } todo_list;
  218. int main( int argc, char *argv[] )
  219. {
  220. int i;
  221. unsigned char tmp[200];
  222. char title[TITLE_LEN];
  223. todo_list todo;
  224. #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
  225. unsigned char alloc_buf[HEAP_SIZE] = { 0 };
  226. #endif
  227. if( argc <= 1 )
  228. {
  229. memset( &todo, 1, sizeof( todo ) );
  230. }
  231. else
  232. {
  233. memset( &todo, 0, sizeof( todo ) );
  234. for( i = 1; i < argc; i++ )
  235. {
  236. if( strcmp( argv[i], "md4" ) == 0 )
  237. todo.md4 = 1;
  238. else if( strcmp( argv[i], "md5" ) == 0 )
  239. todo.md5 = 1;
  240. else if( strcmp( argv[i], "ripemd160" ) == 0 )
  241. todo.ripemd160 = 1;
  242. else if( strcmp( argv[i], "sha1" ) == 0 )
  243. todo.sha1 = 1;
  244. else if( strcmp( argv[i], "sha256" ) == 0 )
  245. todo.sha256 = 1;
  246. else if( strcmp( argv[i], "sha512" ) == 0 )
  247. todo.sha512 = 1;
  248. else if( strcmp( argv[i], "arc4" ) == 0 )
  249. todo.arc4 = 1;
  250. else if( strcmp( argv[i], "des3" ) == 0 )
  251. todo.des3 = 1;
  252. else if( strcmp( argv[i], "des" ) == 0 )
  253. todo.des = 1;
  254. else if( strcmp( argv[i], "aes_cbc" ) == 0 )
  255. todo.aes_cbc = 1;
  256. else if( strcmp( argv[i], "aes_gcm" ) == 0 )
  257. todo.aes_gcm = 1;
  258. else if( strcmp( argv[i], "aes_ccm" ) == 0 )
  259. todo.aes_ccm = 1;
  260. else if( strcmp( argv[i], "aes_cmac" ) == 0 )
  261. todo.aes_cmac = 1;
  262. else if( strcmp( argv[i], "des3_cmac" ) == 0 )
  263. todo.des3_cmac = 1;
  264. else if( strcmp( argv[i], "camellia" ) == 0 )
  265. todo.camellia = 1;
  266. else if( strcmp( argv[i], "blowfish" ) == 0 )
  267. todo.blowfish = 1;
  268. else if( strcmp( argv[i], "havege" ) == 0 )
  269. todo.havege = 1;
  270. else if( strcmp( argv[i], "ctr_drbg" ) == 0 )
  271. todo.ctr_drbg = 1;
  272. else if( strcmp( argv[i], "hmac_drbg" ) == 0 )
  273. todo.hmac_drbg = 1;
  274. else if( strcmp( argv[i], "rsa" ) == 0 )
  275. todo.rsa = 1;
  276. else if( strcmp( argv[i], "dhm" ) == 0 )
  277. todo.dhm = 1;
  278. else if( strcmp( argv[i], "ecdsa" ) == 0 )
  279. todo.ecdsa = 1;
  280. else if( strcmp( argv[i], "ecdh" ) == 0 )
  281. todo.ecdh = 1;
  282. else
  283. {
  284. mbedtls_printf( "Unrecognized option: %s\n", argv[i] );
  285. mbedtls_printf( "Available options: " OPTIONS );
  286. }
  287. }
  288. }
  289. mbedtls_printf( "\n" );
  290. #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
  291. mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
  292. #endif
  293. memset( buf, 0xAA, sizeof( buf ) );
  294. memset( tmp, 0xBB, sizeof( tmp ) );
  295. #if defined(MBEDTLS_MD4_C)
  296. if( todo.md4 )
  297. TIME_AND_TSC( "MD4", mbedtls_md4( buf, BUFSIZE, tmp ) );
  298. #endif
  299. #if defined(MBEDTLS_MD5_C)
  300. if( todo.md5 )
  301. TIME_AND_TSC( "MD5", mbedtls_md5( buf, BUFSIZE, tmp ) );
  302. #endif
  303. #if defined(MBEDTLS_RIPEMD160_C)
  304. if( todo.ripemd160 )
  305. TIME_AND_TSC( "RIPEMD160", mbedtls_ripemd160( buf, BUFSIZE, tmp ) );
  306. #endif
  307. #if defined(MBEDTLS_SHA1_C)
  308. if( todo.sha1 )
  309. TIME_AND_TSC( "SHA-1", mbedtls_sha1( buf, BUFSIZE, tmp ) );
  310. #endif
  311. #if defined(MBEDTLS_SHA256_C)
  312. if( todo.sha256 )
  313. TIME_AND_TSC( "SHA-256", mbedtls_sha256( buf, BUFSIZE, tmp, 0 ) );
  314. #endif
  315. #if defined(MBEDTLS_SHA512_C)
  316. if( todo.sha512 )
  317. TIME_AND_TSC( "SHA-512", mbedtls_sha512( buf, BUFSIZE, tmp, 0 ) );
  318. #endif
  319. #if defined(MBEDTLS_ARC4_C)
  320. if( todo.arc4 )
  321. {
  322. mbedtls_arc4_context arc4;
  323. mbedtls_arc4_init( &arc4 );
  324. mbedtls_arc4_setup( &arc4, tmp, 32 );
  325. TIME_AND_TSC( "ARC4", mbedtls_arc4_crypt( &arc4, BUFSIZE, buf, buf ) );
  326. mbedtls_arc4_free( &arc4 );
  327. }
  328. #endif
  329. #if defined(MBEDTLS_DES_C)
  330. #if defined(MBEDTLS_CIPHER_MODE_CBC)
  331. if( todo.des3 )
  332. {
  333. mbedtls_des3_context des3;
  334. mbedtls_des3_init( &des3 );
  335. mbedtls_des3_set3key_enc( &des3, tmp );
  336. TIME_AND_TSC( "3DES",
  337. mbedtls_des3_crypt_cbc( &des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
  338. mbedtls_des3_free( &des3 );
  339. }
  340. if( todo.des )
  341. {
  342. mbedtls_des_context des;
  343. mbedtls_des_init( &des );
  344. mbedtls_des_setkey_enc( &des, tmp );
  345. TIME_AND_TSC( "DES",
  346. mbedtls_des_crypt_cbc( &des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
  347. mbedtls_des_free( &des );
  348. }
  349. #endif /* MBEDTLS_CIPHER_MODE_CBC */
  350. #if defined(MBEDTLS_CMAC_C)
  351. if( todo.des3_cmac )
  352. {
  353. unsigned char output[8];
  354. const mbedtls_cipher_info_t *cipher_info;
  355. memset( buf, 0, sizeof( buf ) );
  356. memset( tmp, 0, sizeof( tmp ) );
  357. cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_DES_EDE3_ECB );
  358. TIME_AND_TSC( "3DES-CMAC",
  359. mbedtls_cipher_cmac( cipher_info, tmp, 192, buf,
  360. BUFSIZE, output ) );
  361. }
  362. #endif /* MBEDTLS_CMAC_C */
  363. #endif /* MBEDTLS_DES_C */
  364. #if defined(MBEDTLS_AES_C)
  365. #if defined(MBEDTLS_CIPHER_MODE_CBC)
  366. if( todo.aes_cbc )
  367. {
  368. int keysize;
  369. mbedtls_aes_context aes;
  370. mbedtls_aes_init( &aes );
  371. for( keysize = 128; keysize <= 256; keysize += 64 )
  372. {
  373. mbedtls_snprintf( title, sizeof( title ), "AES-CBC-%d", keysize );
  374. memset( buf, 0, sizeof( buf ) );
  375. memset( tmp, 0, sizeof( tmp ) );
  376. mbedtls_aes_setkey_enc( &aes, tmp, keysize );
  377. TIME_AND_TSC( title,
  378. mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
  379. }
  380. mbedtls_aes_free( &aes );
  381. }
  382. #endif
  383. #if defined(MBEDTLS_GCM_C)
  384. if( todo.aes_gcm )
  385. {
  386. int keysize;
  387. mbedtls_gcm_context gcm;
  388. mbedtls_gcm_init( &gcm );
  389. for( keysize = 128; keysize <= 256; keysize += 64 )
  390. {
  391. mbedtls_snprintf( title, sizeof( title ), "AES-GCM-%d", keysize );
  392. memset( buf, 0, sizeof( buf ) );
  393. memset( tmp, 0, sizeof( tmp ) );
  394. mbedtls_gcm_setkey( &gcm, MBEDTLS_CIPHER_ID_AES, tmp, keysize );
  395. TIME_AND_TSC( title,
  396. mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT, BUFSIZE, tmp,
  397. 12, NULL, 0, buf, buf, 16, tmp ) );
  398. mbedtls_gcm_free( &gcm );
  399. }
  400. }
  401. #endif
  402. #if defined(MBEDTLS_CCM_C)
  403. if( todo.aes_ccm )
  404. {
  405. int keysize;
  406. mbedtls_ccm_context ccm;
  407. mbedtls_ccm_init( &ccm );
  408. for( keysize = 128; keysize <= 256; keysize += 64 )
  409. {
  410. mbedtls_snprintf( title, sizeof( title ), "AES-CCM-%d", keysize );
  411. memset( buf, 0, sizeof( buf ) );
  412. memset( tmp, 0, sizeof( tmp ) );
  413. mbedtls_ccm_setkey( &ccm, MBEDTLS_CIPHER_ID_AES, tmp, keysize );
  414. TIME_AND_TSC( title,
  415. mbedtls_ccm_encrypt_and_tag( &ccm, BUFSIZE, tmp,
  416. 12, NULL, 0, buf, buf, tmp, 16 ) );
  417. mbedtls_ccm_free( &ccm );
  418. }
  419. }
  420. #endif
  421. #if defined(MBEDTLS_CMAC_C)
  422. if( todo.aes_cmac )
  423. {
  424. unsigned char output[16];
  425. const mbedtls_cipher_info_t *cipher_info;
  426. mbedtls_cipher_type_t cipher_type;
  427. int keysize;
  428. for( keysize = 128, cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
  429. keysize <= 256;
  430. keysize += 64, cipher_type++ )
  431. {
  432. mbedtls_snprintf( title, sizeof( title ), "AES-CMAC-%d", keysize );
  433. memset( buf, 0, sizeof( buf ) );
  434. memset( tmp, 0, sizeof( tmp ) );
  435. cipher_info = mbedtls_cipher_info_from_type( cipher_type );
  436. TIME_AND_TSC( title,
  437. mbedtls_cipher_cmac( cipher_info, tmp, keysize,
  438. buf, BUFSIZE, output ) );
  439. }
  440. memset( buf, 0, sizeof( buf ) );
  441. memset( tmp, 0, sizeof( tmp ) );
  442. TIME_AND_TSC( "AES-CMAC-PRF-128",
  443. mbedtls_aes_cmac_prf_128( tmp, 16, buf, BUFSIZE,
  444. output ) );
  445. }
  446. #endif /* MBEDTLS_CMAC_C */
  447. #endif /* MBEDTLS_AES_C */
  448. #if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
  449. if( todo.camellia )
  450. {
  451. int keysize;
  452. mbedtls_camellia_context camellia;
  453. mbedtls_camellia_init( &camellia );
  454. for( keysize = 128; keysize <= 256; keysize += 64 )
  455. {
  456. mbedtls_snprintf( title, sizeof( title ), "CAMELLIA-CBC-%d", keysize );
  457. memset( buf, 0, sizeof( buf ) );
  458. memset( tmp, 0, sizeof( tmp ) );
  459. mbedtls_camellia_setkey_enc( &camellia, tmp, keysize );
  460. TIME_AND_TSC( title,
  461. mbedtls_camellia_crypt_cbc( &camellia, MBEDTLS_CAMELLIA_ENCRYPT,
  462. BUFSIZE, tmp, buf, buf ) );
  463. }
  464. mbedtls_camellia_free( &camellia );
  465. }
  466. #endif
  467. #if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
  468. if( todo.blowfish )
  469. {
  470. int keysize;
  471. mbedtls_blowfish_context blowfish;
  472. mbedtls_blowfish_init( &blowfish );
  473. for( keysize = 128; keysize <= 256; keysize += 64 )
  474. {
  475. mbedtls_snprintf( title, sizeof( title ), "BLOWFISH-CBC-%d", keysize );
  476. memset( buf, 0, sizeof( buf ) );
  477. memset( tmp, 0, sizeof( tmp ) );
  478. mbedtls_blowfish_setkey( &blowfish, tmp, keysize );
  479. TIME_AND_TSC( title,
  480. mbedtls_blowfish_crypt_cbc( &blowfish, MBEDTLS_BLOWFISH_ENCRYPT, BUFSIZE,
  481. tmp, buf, buf ) );
  482. }
  483. mbedtls_blowfish_free( &blowfish );
  484. }
  485. #endif
  486. #if defined(MBEDTLS_HAVEGE_C)
  487. if( todo.havege )
  488. {
  489. mbedtls_havege_state hs;
  490. mbedtls_havege_init( &hs );
  491. TIME_AND_TSC( "HAVEGE", mbedtls_havege_random( &hs, buf, BUFSIZE ) );
  492. mbedtls_havege_free( &hs );
  493. }
  494. #endif
  495. #if defined(MBEDTLS_CTR_DRBG_C)
  496. if( todo.ctr_drbg )
  497. {
  498. mbedtls_ctr_drbg_context ctr_drbg;
  499. mbedtls_ctr_drbg_init( &ctr_drbg );
  500. if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
  501. mbedtls_exit(1);
  502. TIME_AND_TSC( "CTR_DRBG (NOPR)",
  503. if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
  504. mbedtls_exit(1) );
  505. if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
  506. mbedtls_exit(1);
  507. mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );
  508. TIME_AND_TSC( "CTR_DRBG (PR)",
  509. if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
  510. mbedtls_exit(1) );
  511. mbedtls_ctr_drbg_free( &ctr_drbg );
  512. }
  513. #endif
  514. #if defined(MBEDTLS_HMAC_DRBG_C)
  515. if( todo.hmac_drbg )
  516. {
  517. mbedtls_hmac_drbg_context hmac_drbg;
  518. const mbedtls_md_info_t *md_info;
  519. mbedtls_hmac_drbg_init( &hmac_drbg );
  520. #if defined(MBEDTLS_SHA1_C)
  521. if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL )
  522. mbedtls_exit(1);
  523. if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
  524. mbedtls_exit(1);
  525. TIME_AND_TSC( "HMAC_DRBG SHA-1 (NOPR)",
  526. if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 )
  527. mbedtls_exit(1) );
  528. mbedtls_hmac_drbg_free( &hmac_drbg );
  529. if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
  530. mbedtls_exit(1);
  531. mbedtls_hmac_drbg_set_prediction_resistance( &hmac_drbg,
  532. MBEDTLS_HMAC_DRBG_PR_ON );
  533. TIME_AND_TSC( "HMAC_DRBG SHA-1 (PR)",
  534. if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 )
  535. mbedtls_exit(1) );
  536. mbedtls_hmac_drbg_free( &hmac_drbg );
  537. #endif
  538. #if defined(MBEDTLS_SHA256_C)
  539. if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ) ) == NULL )
  540. mbedtls_exit(1);
  541. if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
  542. mbedtls_exit(1);
  543. TIME_AND_TSC( "HMAC_DRBG SHA-256 (NOPR)",
  544. if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 )
  545. mbedtls_exit(1) );
  546. mbedtls_hmac_drbg_free( &hmac_drbg );
  547. if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 )
  548. mbedtls_exit(1);
  549. mbedtls_hmac_drbg_set_prediction_resistance( &hmac_drbg,
  550. MBEDTLS_HMAC_DRBG_PR_ON );
  551. TIME_AND_TSC( "HMAC_DRBG SHA-256 (PR)",
  552. if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 )
  553. mbedtls_exit(1) );
  554. mbedtls_hmac_drbg_free( &hmac_drbg );
  555. #endif
  556. }
  557. #endif
  558. #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
  559. if( todo.rsa )
  560. {
  561. int keysize;
  562. mbedtls_rsa_context rsa;
  563. for( keysize = 2048; keysize <= 4096; keysize *= 2 )
  564. {
  565. mbedtls_snprintf( title, sizeof( title ), "RSA-%d", keysize );
  566. mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
  567. mbedtls_rsa_gen_key( &rsa, myrand, NULL, keysize, 65537 );
  568. TIME_PUBLIC( title, " public",
  569. buf[0] = 0;
  570. ret = mbedtls_rsa_public( &rsa, buf, buf ) );
  571. TIME_PUBLIC( title, "private",
  572. buf[0] = 0;
  573. ret = mbedtls_rsa_private( &rsa, myrand, NULL, buf, buf ) );
  574. mbedtls_rsa_free( &rsa );
  575. }
  576. }
  577. #endif
  578. #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_BIGNUM_C)
  579. if( todo.dhm )
  580. {
  581. int dhm_sizes[] = { 2048, 3072 };
  582. const char *dhm_P[] = {
  583. MBEDTLS_DHM_RFC3526_MODP_2048_P,
  584. MBEDTLS_DHM_RFC3526_MODP_3072_P,
  585. };
  586. const char *dhm_G[] = {
  587. MBEDTLS_DHM_RFC3526_MODP_2048_G,
  588. MBEDTLS_DHM_RFC3526_MODP_3072_G,
  589. };
  590. mbedtls_dhm_context dhm;
  591. size_t olen;
  592. for( i = 0; (size_t) i < sizeof( dhm_sizes ) / sizeof( dhm_sizes[0] ); i++ )
  593. {
  594. mbedtls_dhm_init( &dhm );
  595. if( mbedtls_mpi_read_string( &dhm.P, 16, dhm_P[i] ) != 0 ||
  596. mbedtls_mpi_read_string( &dhm.G, 16, dhm_G[i] ) != 0 )
  597. {
  598. mbedtls_exit( 1 );
  599. }
  600. dhm.len = mbedtls_mpi_size( &dhm.P );
  601. mbedtls_dhm_make_public( &dhm, (int) dhm.len, buf, dhm.len, myrand, NULL );
  602. if( mbedtls_mpi_copy( &dhm.GY, &dhm.GX ) != 0 )
  603. mbedtls_exit( 1 );
  604. mbedtls_snprintf( title, sizeof( title ), "DHE-%d", dhm_sizes[i] );
  605. TIME_PUBLIC( title, "handshake",
  606. ret |= mbedtls_dhm_make_public( &dhm, (int) dhm.len, buf, dhm.len,
  607. myrand, NULL );
  608. ret |= mbedtls_dhm_calc_secret( &dhm, buf, sizeof( buf ), &olen, myrand, NULL ) );
  609. mbedtls_snprintf( title, sizeof( title ), "DH-%d", dhm_sizes[i] );
  610. TIME_PUBLIC( title, "handshake",
  611. ret |= mbedtls_dhm_calc_secret( &dhm, buf, sizeof( buf ), &olen, myrand, NULL ) );
  612. mbedtls_dhm_free( &dhm );
  613. }
  614. }
  615. #endif
  616. #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA256_C)
  617. if( todo.ecdsa )
  618. {
  619. mbedtls_ecdsa_context ecdsa;
  620. const mbedtls_ecp_curve_info *curve_info;
  621. size_t sig_len;
  622. memset( buf, 0x2A, sizeof( buf ) );
  623. for( curve_info = mbedtls_ecp_curve_list();
  624. curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
  625. curve_info++ )
  626. {
  627. mbedtls_ecdsa_init( &ecdsa );
  628. if( mbedtls_ecdsa_genkey( &ecdsa, curve_info->grp_id, myrand, NULL ) != 0 )
  629. mbedtls_exit( 1 );
  630. ecp_clear_precomputed( &ecdsa.grp );
  631. mbedtls_snprintf( title, sizeof( title ), "ECDSA-%s",
  632. curve_info->name );
  633. TIME_PUBLIC( title, "sign",
  634. ret = mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
  635. tmp, &sig_len, myrand, NULL ) );
  636. mbedtls_ecdsa_free( &ecdsa );
  637. }
  638. for( curve_info = mbedtls_ecp_curve_list();
  639. curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
  640. curve_info++ )
  641. {
  642. mbedtls_ecdsa_init( &ecdsa );
  643. if( mbedtls_ecdsa_genkey( &ecdsa, curve_info->grp_id, myrand, NULL ) != 0 ||
  644. mbedtls_ecdsa_write_signature( &ecdsa, MBEDTLS_MD_SHA256, buf, curve_info->bit_size,
  645. tmp, &sig_len, myrand, NULL ) != 0 )
  646. {
  647. mbedtls_exit( 1 );
  648. }
  649. ecp_clear_precomputed( &ecdsa.grp );
  650. mbedtls_snprintf( title, sizeof( title ), "ECDSA-%s",
  651. curve_info->name );
  652. TIME_PUBLIC( title, "verify",
  653. ret = mbedtls_ecdsa_read_signature( &ecdsa, buf, curve_info->bit_size,
  654. tmp, sig_len ) );
  655. mbedtls_ecdsa_free( &ecdsa );
  656. }
  657. }
  658. #endif
  659. #if defined(MBEDTLS_ECDH_C)
  660. if( todo.ecdh )
  661. {
  662. mbedtls_ecdh_context ecdh;
  663. #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
  664. mbedtls_mpi z;
  665. #endif
  666. const mbedtls_ecp_curve_info *curve_info;
  667. size_t olen;
  668. for( curve_info = mbedtls_ecp_curve_list();
  669. curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
  670. curve_info++ )
  671. {
  672. mbedtls_ecdh_init( &ecdh );
  673. if( mbedtls_ecp_group_load( &ecdh.grp, curve_info->grp_id ) != 0 ||
  674. mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
  675. myrand, NULL ) != 0 ||
  676. mbedtls_ecp_copy( &ecdh.Qp, &ecdh.Q ) != 0 )
  677. {
  678. mbedtls_exit( 1 );
  679. }
  680. ecp_clear_precomputed( &ecdh.grp );
  681. mbedtls_snprintf( title, sizeof( title ), "ECDHE-%s",
  682. curve_info->name );
  683. TIME_PUBLIC( title, "handshake",
  684. ret |= mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
  685. myrand, NULL );
  686. ret |= mbedtls_ecdh_calc_secret( &ecdh, &olen, buf, sizeof( buf ),
  687. myrand, NULL ) );
  688. mbedtls_ecdh_free( &ecdh );
  689. }
  690. /* Curve25519 needs to be handled separately */
  691. #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
  692. mbedtls_ecdh_init( &ecdh );
  693. mbedtls_mpi_init( &z );
  694. if( mbedtls_ecp_group_load( &ecdh.grp, MBEDTLS_ECP_DP_CURVE25519 ) != 0 ||
  695. mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Qp, myrand, NULL ) != 0 )
  696. {
  697. mbedtls_exit( 1 );
  698. }
  699. TIME_PUBLIC( "ECDHE-Curve25519", "handshake",
  700. ret |= mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Q,
  701. myrand, NULL );
  702. ret |= mbedtls_ecdh_compute_shared( &ecdh.grp, &z, &ecdh.Qp, &ecdh.d,
  703. myrand, NULL ) );
  704. mbedtls_ecdh_free( &ecdh );
  705. mbedtls_mpi_free( &z );
  706. #endif
  707. for( curve_info = mbedtls_ecp_curve_list();
  708. curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
  709. curve_info++ )
  710. {
  711. mbedtls_ecdh_init( &ecdh );
  712. if( mbedtls_ecp_group_load( &ecdh.grp, curve_info->grp_id ) != 0 ||
  713. mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
  714. myrand, NULL ) != 0 ||
  715. mbedtls_ecp_copy( &ecdh.Qp, &ecdh.Q ) != 0 ||
  716. mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
  717. myrand, NULL ) != 0 )
  718. {
  719. mbedtls_exit( 1 );
  720. }
  721. ecp_clear_precomputed( &ecdh.grp );
  722. mbedtls_snprintf( title, sizeof( title ), "ECDH-%s",
  723. curve_info->name );
  724. TIME_PUBLIC( title, "handshake",
  725. ret |= mbedtls_ecdh_calc_secret( &ecdh, &olen, buf, sizeof( buf ),
  726. myrand, NULL ) );
  727. mbedtls_ecdh_free( &ecdh );
  728. }
  729. /* Curve25519 needs to be handled separately */
  730. #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
  731. mbedtls_ecdh_init( &ecdh );
  732. mbedtls_mpi_init( &z );
  733. if( mbedtls_ecp_group_load( &ecdh.grp, MBEDTLS_ECP_DP_CURVE25519 ) != 0 ||
  734. mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Qp,
  735. myrand, NULL ) != 0 ||
  736. mbedtls_ecdh_gen_public( &ecdh.grp, &ecdh.d, &ecdh.Q, myrand, NULL ) != 0 )
  737. {
  738. mbedtls_exit( 1 );
  739. }
  740. TIME_PUBLIC( "ECDH-Curve25519", "handshake",
  741. ret |= mbedtls_ecdh_compute_shared( &ecdh.grp, &z, &ecdh.Qp, &ecdh.d,
  742. myrand, NULL ) );
  743. mbedtls_ecdh_free( &ecdh );
  744. mbedtls_mpi_free( &z );
  745. #endif
  746. }
  747. #endif
  748. mbedtls_printf( "\n" );
  749. #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
  750. mbedtls_memory_buffer_alloc_free();
  751. #endif
  752. #if defined(_WIN32)
  753. mbedtls_printf( " Press Enter to exit this program.\n" );
  754. fflush( stdout ); getchar();
  755. #endif
  756. return( 0 );
  757. }
  758. #endif /* MBEDTLS_TIMING_C */