benchmark.c 45 KB

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