benchmark.c 36 KB

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