wolfssl_example.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355
  1. /* wolfssl_example.c
  2. *
  3. * Copyright (C) 2006-2020 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #include "wolfssl_example.h"
  22. /* force certificate test buffers to be included via headers */
  23. #undef USE_CERT_BUFFERS_2048
  24. #define USE_CERT_BUFFERS_2048
  25. #undef USE_CERT_BUFFERS_256
  26. #define USE_CERT_BUFFERS_256
  27. #include <wolfssl/certs_test.h>
  28. #include <wolfssl/wolfcrypt/hash.h> /* WC_MAX_DIGEST_SIZE */
  29. #define WOLFSSL_DEBUG_MEMORY
  30. #ifdef WOLFSSL_DEBUG_MEMORY
  31. /* for memory debugging */
  32. #include <task.h>
  33. #endif
  34. /*****************************************************************************
  35. * Configuration
  36. ****************************************************************************/
  37. /* Defaults for configuration parameters */
  38. #define BENCH_DEFAULT_HOST "localhost"
  39. #define BENCH_DEFAULT_PORT 11112
  40. #define BENCH_RUNTIME_SEC 20
  41. #define BENCH_SHOW_PEER_INFO 1
  42. #define TEST_PACKET_SIZE (2 * 1024) /* TLS packet size */
  43. #define TEST_MAX_SIZE (32 * 1024) /* Total bytes to benchmark */
  44. /* Must be large enough to handle max packet size - TLS header MAX_MSG_EXTRA + MAX DIGEST */
  45. #define MEM_BUFFER_SZ (TEST_PACKET_SIZE + 38 + WC_MAX_DIGEST_SIZE)
  46. #define SHOW_VERBOSE 0 /* Default output is tab delimited format */
  47. #ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE
  48. #define WOLFSSL_CIPHER_LIST_MAX_SIZE 2048
  49. #endif
  50. #if 0
  51. /* define this to test only a specific cipher suite(s) (colon separated) */
  52. #define TEST_CIPHER_SUITE "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
  53. #endif
  54. /*****************************************************************************
  55. * Private types/enumerations/variables
  56. ****************************************************************************/
  57. /* UART definitions */
  58. extern UART_HandleTypeDef huart4;
  59. extern SPI_HandleTypeDef hspi1;
  60. /*****************************************************************************
  61. * Public types/enumerations/variables
  62. ****************************************************************************/
  63. typedef struct func_args {
  64. int argc;
  65. char** argv;
  66. int return_code;
  67. } func_args;
  68. const char menu1[] = "\r\n"
  69. "\tt. WolfCrypt Test\r\n"
  70. "\tb. WolfCrypt Benchmark\r\n"
  71. "\tl. WolfSSL TLS Bench\r\n"
  72. "\te. Show Cipher List\r\n";
  73. static const char* kShutdown = "shutdown";
  74. #if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
  75. !defined(WOLFCRYPT_ONLY)
  76. static const char* kTestStr =
  77. "Biodiesel cupidatat marfa, cliche aute put a bird on it incididunt elit\n"
  78. "polaroid. Sunt tattooed bespoke reprehenderit. Sint twee organic id\n"
  79. "marfa. Commodo veniam ad esse gastropub. 3 wolf moon sartorial vero,\n"
  80. "plaid delectus biodiesel squid +1 vice. Post-ironic keffiyeh leggings\n"
  81. "selfies cray fap hoodie, forage anim. Carles cupidatat shoreditch, VHS\n"
  82. "small batch meggings kogi dolore food truck bespoke gastropub.\n"
  83. "\n"
  84. "Terry richardson adipisicing actually typewriter tumblr, twee whatever\n"
  85. "four loko you probably haven't heard of them high life. Messenger bag\n"
  86. "whatever tattooed deep v mlkshk. Brooklyn pinterest assumenda chillwave\n"
  87. "et, banksy ullamco messenger bag umami pariatur direct trade forage.\n"
  88. "Typewriter culpa try-hard, pariatur sint brooklyn meggings. Gentrify\n"
  89. "food truck next level, tousled irony non semiotics PBR ethical anim cred\n"
  90. "readymade. Mumblecore brunch lomo odd future, portland organic terry\n"
  91. "richardson elit leggings adipisicing ennui raw denim banjo hella. Godard\n"
  92. "mixtape polaroid, pork belly readymade organic cray typewriter helvetica\n"
  93. "four loko whatever street art yr farm-to-table.\n"
  94. "\n"
  95. "Vinyl keytar vice tofu. Locavore you probably haven't heard of them pug\n"
  96. "pickled, hella tonx labore truffaut DIY mlkshk elit cosby sweater sint\n"
  97. "et mumblecore. Elit swag semiotics, reprehenderit DIY sartorial nisi ugh\n"
  98. "nesciunt pug pork belly wayfarers selfies delectus. Ethical hoodie\n"
  99. "seitan fingerstache kale chips. Terry richardson artisan williamsburg,\n"
  100. "eiusmod fanny pack irony tonx ennui lo-fi incididunt tofu YOLO\n"
  101. "readymade. 8-bit sed ethnic beard officia. Pour-over iphone DIY butcher,\n"
  102. "ethnic art party qui letterpress nisi proident jean shorts mlkshk\n"
  103. "locavore.\n"
  104. "\n"
  105. "Narwhal flexitarian letterpress, do gluten-free voluptate next level\n"
  106. "banh mi tonx incididunt carles DIY. Odd future nulla 8-bit beard ut\n"
  107. "cillum pickled velit, YOLO officia you probably haven't heard of them\n"
  108. "trust fund gastropub. Nisi adipisicing tattooed, Austin mlkshk 90's\n"
  109. "small batch american apparel. Put a bird on it cosby sweater before they\n"
  110. "sold out pork belly kogi hella. Street art mollit sustainable polaroid,\n"
  111. "DIY ethnic ea pug beard dreamcatcher cosby sweater magna scenester nisi.\n"
  112. "Sed pork belly skateboard mollit, labore proident eiusmod. Sriracha\n"
  113. "excepteur cosby sweater, anim deserunt laborum eu aliquip ethical et\n"
  114. "neutra PBR selvage.\n"
  115. "\n"
  116. "Raw denim pork belly truffaut, irony plaid sustainable put a bird on it\n"
  117. "next level jean shorts exercitation. Hashtag keytar whatever, nihil\n"
  118. "authentic aliquip disrupt laborum. Tattooed selfies deserunt trust fund\n"
  119. "wayfarers. 3 wolf moon synth church-key sartorial, gastropub leggings\n"
  120. "tattooed. Labore high life commodo, meggings raw denim fingerstache pug\n"
  121. "trust fund leggings seitan forage. Nostrud ullamco duis, reprehenderit\n"
  122. "incididunt flannel sustainable helvetica pork belly pug banksy you\n"
  123. "probably haven't heard of them nesciunt farm-to-table. Disrupt nostrud\n"
  124. "mollit magna, sriracha sartorial helvetica.\n"
  125. "\n"
  126. "Nulla kogi reprehenderit, skateboard sustainable duis adipisicing viral\n"
  127. "ad fanny pack salvia. Fanny pack trust fund you probably haven't heard\n"
  128. "of them YOLO vice nihil. Keffiyeh cray lo-fi pinterest cardigan aliqua,\n"
  129. "reprehenderit aute. Culpa tousled williamsburg, marfa lomo actually anim\n"
  130. "skateboard. Iphone aliqua ugh, semiotics pariatur vero readymade\n"
  131. "organic. Marfa squid nulla, in laborum disrupt laboris irure gastropub.\n"
  132. "Veniam sunt food truck leggings, sint vinyl fap.\n"
  133. "\n"
  134. "Hella dolore pork belly, truffaut carles you probably haven't heard of\n"
  135. "them PBR helvetica in sapiente. Fashion axe ugh bushwick american\n"
  136. "apparel. Fingerstache sed iphone, jean shorts blue bottle nisi bushwick\n"
  137. "flexitarian officia veniam plaid bespoke fap YOLO lo-fi. Blog\n"
  138. "letterpress mumblecore, food truck id cray brooklyn cillum ad sed.\n"
  139. "Assumenda chambray wayfarers vinyl mixtape sustainable. VHS vinyl\n"
  140. "delectus, culpa williamsburg polaroid cliche swag church-key synth kogi\n"
  141. "magna pop-up literally. Swag thundercats ennui shoreditch vegan\n"
  142. "pitchfork neutra truffaut etsy, sed single-origin coffee craft beer.\n"
  143. "\n"
  144. "Odio letterpress brooklyn elit. Nulla single-origin coffee in occaecat\n"
  145. "meggings. Irony meggings 8-bit, chillwave lo-fi adipisicing cred\n"
  146. "dreamcatcher veniam. Put a bird on it irony umami, trust fund bushwick\n"
  147. "locavore kale chips. Sriracha swag thundercats, chillwave disrupt\n"
  148. "tousled beard mollit mustache leggings portland next level. Nihil esse\n"
  149. "est, skateboard art party etsy thundercats sed dreamcatcher ut iphone\n"
  150. "swag consectetur et. Irure skateboard banjo, nulla deserunt messenger\n"
  151. "bag dolor terry richardson sapiente.\n";
  152. #if !defined(NO_DH)
  153. #define MIN_DHKEY_BITS 1024
  154. /* dh2048 p */
  155. static const unsigned char p[] =
  156. {
  157. 0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba, 0x59, 0x06, 0x3c, 0xbc, 0x30,
  158. 0xd5, 0xf5, 0x00, 0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6, 0x25, 0x27,
  159. 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a, 0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84,
  160. 0xbf, 0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a, 0xc5, 0xbe, 0x72, 0x5c,
  161. 0xa7, 0xe7, 0x91, 0xe6, 0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48, 0xc7,
  162. 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d, 0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46,
  163. 0x3e, 0x19, 0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f, 0x2b, 0x96, 0x17,
  164. 0x39, 0x6d, 0x30, 0x8d, 0x2a, 0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
  165. 0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04, 0x83, 0x57, 0x30, 0xfb, 0xda,
  166. 0x76, 0x93, 0x38, 0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5, 0xb7, 0xc8,
  167. 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e, 0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e,
  168. 0x5a, 0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc, 0x16, 0x30, 0xdb, 0x0c,
  169. 0xfc, 0xc5, 0x62, 0xa7, 0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36, 0xf6,
  170. 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90, 0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3,
  171. 0x1a, 0xc3, 0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48, 0x4e, 0x22, 0x73,
  172. 0x6f, 0xc3, 0x5f, 0xd4, 0x9a, 0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
  173. 0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b, 0xa6, 0xb9, 0xcd, 0x29, 0xbf,
  174. 0x68, 0x1f, 0x08, 0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6, 0x06, 0x65,
  175. 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b, 0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7,
  176. 0xfa, 0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x93
  177. };
  178. /* dh2048 g */
  179. static const unsigned char g[] =
  180. {
  181. 0x02,
  182. };
  183. #endif /* !NO_DH */
  184. typedef struct {
  185. unsigned char buf[MEM_BUFFER_SZ];
  186. int write_bytes;
  187. int write_idx;
  188. int read_bytes;
  189. int read_idx;
  190. } memBuf_t;
  191. typedef struct {
  192. double connTime;
  193. double rxTime;
  194. double txTime;
  195. int connCount;
  196. int rxTotal;
  197. int txTotal;
  198. } stats_t;
  199. typedef struct {
  200. int ret;
  201. osThreadDef_t threadDef;
  202. osThreadId threadId;
  203. osSemaphoreDef_t mutexDef;
  204. osSemaphoreId mutex;
  205. byte shutdown:1;
  206. byte done:1;
  207. } side_t;
  208. typedef struct {
  209. const char* cipher;
  210. const char* host;
  211. word32 port;
  212. int packetSize; /* The data payload size in the packet */
  213. int maxSize;
  214. int runTimeSec;
  215. int showPeerInfo;
  216. int showVerbose;
  217. int doShutdown;
  218. side_t client;
  219. side_t server;
  220. /* client messages to server in memory */
  221. memBuf_t to_server;
  222. /* server messages to client in memory */
  223. memBuf_t to_client;
  224. /* server */
  225. stats_t server_stats;
  226. /* client */
  227. stats_t client_stats;
  228. } info_t;
  229. extern RTC_HandleTypeDef hrtc;
  230. double current_time(void)
  231. {
  232. RTC_TimeTypeDef time;
  233. RTC_DateTypeDef date;
  234. uint32_t subsec;
  235. /* must get time and date here due to STM32 HW bug */
  236. HAL_RTC_GetTime(&hrtc, &time, FORMAT_BIN);
  237. HAL_RTC_GetDate(&hrtc, &date, FORMAT_BIN);
  238. subsec = (255 - time.SubSeconds) * 1000 / 255;
  239. (void) date;
  240. /* return seconds.milliseconds */
  241. return ((double) time.Hours * 24) + ((double) time.Minutes * 60)
  242. + (double) time.Seconds + ((double) subsec / 1000);
  243. }
  244. static double gettime_secs(int reset)
  245. {
  246. return current_time();
  247. }
  248. static void PrintTlsStats(stats_t* wcStat, const char* desc, const char* cipher, int verbose)
  249. {
  250. const char* formatStr;
  251. if (verbose) {
  252. formatStr = "wolfSSL %s Benchmark on %s:\n"
  253. "\tTotal : %9d bytes\n"
  254. "\tNum Conns : %9d\n"
  255. "\tRx Total : %9.3f ms\n"
  256. "\tTx Total : %9.3f ms\n"
  257. "\tRx : %9.3f MB/s\n"
  258. "\tTx : %9.3f MB/s\n"
  259. "\tConnect : %9.3f ms\n"
  260. "\tConnect Avg : %9.3f ms\n";
  261. }
  262. else {
  263. formatStr = "%-6s %-33s %11d %9d %9.3f %9.3f %9.3f %9.3f %17.3f %15.3f\n";
  264. }
  265. printf(formatStr,
  266. desc,
  267. cipher,
  268. wcStat->txTotal + wcStat->rxTotal,
  269. wcStat->connCount,
  270. wcStat->rxTime * 1000,
  271. wcStat->txTime * 1000,
  272. wcStat->rxTotal / wcStat->rxTime / 1024 / 1024,
  273. wcStat->txTotal / wcStat->txTime / 1024 / 1024,
  274. wcStat->connTime * 1000,
  275. wcStat->connTime * 1000 / wcStat->connCount);
  276. }
  277. static void ShowCiphers(void)
  278. {
  279. int ret;
  280. char* ciphers = (char*)XMALLOC(WOLFSSL_CIPHER_LIST_MAX_SIZE, NULL,
  281. DYNAMIC_TYPE_TMP_BUFFER);
  282. if (ciphers) {
  283. ret = wolfSSL_get_ciphers(ciphers, WOLFSSL_CIPHER_LIST_MAX_SIZE);
  284. if (ret == WOLFSSL_SUCCESS)
  285. printf("%s\n", ciphers);
  286. XFREE(ciphers, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  287. }
  288. }
  289. static void PrintMemStats(void)
  290. {
  291. #ifdef WOLFSSL_DEBUG_MEMORY
  292. printf("\nHeap MinEver %d, Free %d, Stack %lu\n",
  293. xPortGetMinimumEverFreeHeapSize(),
  294. xPortGetFreeHeapSize(),
  295. uxTaskGetStackHighWaterMark(NULL));
  296. #endif
  297. }
  298. #if defined(KEEP_PEER_CERT) || defined(KEEP_OUR_CERT)
  299. static const char* client_showx509_msg[] = {
  300. "issuer",
  301. "subject",
  302. "altname",
  303. "serial number",
  304. NULL
  305. };
  306. static void ShowX509(WOLFSSL_X509* x509, const char* hdr)
  307. {
  308. char* altName;
  309. char* issuer;
  310. char* subject;
  311. byte serial[32];
  312. int ret;
  313. int sz = sizeof(serial);
  314. const char** words = client_showx509_msg;
  315. if (x509 == NULL) {
  316. printf("%s No Cert\n", hdr);
  317. return;
  318. }
  319. issuer = wolfSSL_X509_NAME_oneline(
  320. wolfSSL_X509_get_issuer_name(x509), 0, 0);
  321. subject = wolfSSL_X509_NAME_oneline(
  322. wolfSSL_X509_get_subject_name(x509), 0, 0);
  323. printf("%s\n %s : %s\n %s: %s\n", hdr, words[0], issuer, words[1], subject);
  324. while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
  325. printf(" %s = %s\n", words[2], altName);
  326. ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
  327. if (ret == WOLFSSL_SUCCESS) {
  328. int i;
  329. int strLen;
  330. char serialMsg[80];
  331. /* testsuite has multiple threads writing to stdout, get output
  332. message ready to write once */
  333. strLen = sprintf(serialMsg, " %s", words[3]);
  334. for (i = 0; i < sz; i++)
  335. sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
  336. printf("%s\n", serialMsg);
  337. }
  338. XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
  339. XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
  340. #if defined(OPENSSL_EXTRA)
  341. {
  342. WOLFSSL_BIO* bio;
  343. char buf[256]; /* should be size of ASN_NAME_MAX */
  344. int textSz;
  345. /* print out domain component if certificate has it */
  346. textSz = wolfSSL_X509_NAME_get_text_by_NID(
  347. wolfSSL_X509_get_subject_name(x509), NID_domainComponent,
  348. buf, sizeof(buf));
  349. if (textSz > 0) {
  350. printf("Domain Component = %s\n", buf);
  351. }
  352. bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
  353. if (bio != NULL) {
  354. wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
  355. wolfSSL_X509_print(bio, x509);
  356. wolfSSL_BIO_free(bio);
  357. }
  358. }
  359. #endif /* OPENSSL_EXTRA */
  360. }
  361. #endif
  362. static const char* client_showpeer_msg[] = {
  363. "SSL version is",
  364. "SSL cipher suite is",
  365. "SSL curve name is",
  366. "SSL DH size is",
  367. "SSL reused session",
  368. "Alternate cert chain used",
  369. "peer's cert info:",
  370. NULL
  371. };
  372. static void ShowPeer(WOLFSSL* ssl)
  373. {
  374. WOLFSSL_CIPHER* cipher;
  375. const char** words = client_showpeer_msg;
  376. #if defined(HAVE_ECC) || !defined(NO_DH)
  377. const char *name;
  378. #endif
  379. #ifndef NO_DH
  380. int bits;
  381. #endif
  382. #ifdef KEEP_PEER_CERT
  383. WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
  384. if (peer)
  385. ShowX509(peer, words[6]);
  386. else
  387. printf("peer has no cert!\n");
  388. wolfSSL_FreeX509(peer);
  389. #endif
  390. #if defined(KEEP_OUR_CERT) && \
  391. (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
  392. ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
  393. printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
  394. #endif /* SHOW_CERTS && KEEP_OUR_CERT */
  395. printf("%s %s\n", words[0], wolfSSL_get_version(ssl));
  396. cipher = wolfSSL_get_current_cipher(ssl);
  397. #ifdef HAVE_QSH
  398. printf("%s %s%s\n", words[1], (wolfSSL_isQSH(ssl))? "QSH:": "",
  399. wolfSSL_CIPHER_get_name(cipher));
  400. #else
  401. printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher));
  402. #endif
  403. #if defined(HAVE_ECC) || !defined(NO_DH)
  404. if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
  405. printf("%s %s\n", words[2], name);
  406. #endif
  407. #ifndef NO_DH
  408. else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
  409. printf("%s %d bits\n", words[3], bits);
  410. #endif
  411. if (wolfSSL_session_reused(ssl))
  412. printf("%s\n", words[4]);
  413. #ifdef WOLFSSL_ALT_CERT_CHAINS
  414. if (wolfSSL_is_peer_alt_cert_chain(ssl))
  415. printf("%s\n", words[5]);
  416. #endif
  417. (void)ssl;
  418. }
  419. /* server send callback */
  420. static int ServerMemSend(info_t* info, char* buf, int sz)
  421. {
  422. osSemaphoreWait(info->client.mutex, osWaitForever);
  423. #ifndef BENCH_USE_NONBLOCK
  424. /* check for overflow */
  425. if (info->to_client.write_idx + sz > MEM_BUFFER_SZ) {
  426. osSemaphoreRelease(info->client.mutex);
  427. printf("ServerMemSend overflow\n");
  428. return -1;
  429. }
  430. #else
  431. if (info->to_client.write_idx + sz > MEM_BUFFER_SZ)
  432. sz = MEM_BUFFER_SZ - info->to_client.write_idx;
  433. #endif
  434. XMEMCPY(&info->to_client.buf[info->to_client.write_idx], buf, sz);
  435. info->to_client.write_idx += sz;
  436. info->to_client.write_bytes += sz;
  437. osSignalSet(info->client.threadId, 1);
  438. osSemaphoreRelease(info->client.mutex);
  439. #ifdef BENCH_USE_NONBLOCK
  440. if (sz == 0)
  441. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  442. #endif
  443. return sz;
  444. }
  445. /* server recv callback */
  446. static int ServerMemRecv(info_t* info, char* buf, int sz)
  447. {
  448. osSemaphoreWait(info->server.mutex, osWaitForever);
  449. #ifndef BENCH_USE_NONBLOCK
  450. while (info->to_server.write_idx - info->to_server.read_idx < sz &&
  451. !info->client.done) {
  452. osSemaphoreRelease(info->server.mutex);
  453. osSignalWait(1, osWaitForever);
  454. osSemaphoreWait(info->server.mutex, osWaitForever);
  455. }
  456. #else
  457. if (info->to_server.write_idx - info->to_server.read_idx < sz)
  458. sz = info->to_server.write_idx - info->to_server.read_idx;
  459. #endif
  460. XMEMCPY(buf, &info->to_server.buf[info->to_server.read_idx], sz);
  461. info->to_server.read_idx += sz;
  462. info->to_server.read_bytes += sz;
  463. /* if the rx has caught up with pending then reset buffer positions */
  464. if (info->to_server.read_bytes == info->to_server.write_bytes) {
  465. info->to_server.read_bytes = info->to_server.read_idx = 0;
  466. info->to_server.write_bytes = info->to_server.write_idx = 0;
  467. }
  468. osSemaphoreRelease(info->server.mutex);
  469. #ifdef BENCH_USE_NONBLOCK
  470. if (sz == 0)
  471. return WOLFSSL_CBIO_ERR_WANT_READ;
  472. #endif
  473. return sz;
  474. }
  475. /* client send callback */
  476. static int ClientMemSend(info_t* info, char* buf, int sz)
  477. {
  478. osSemaphoreWait(info->server.mutex, osWaitForever);
  479. #ifndef BENCH_USE_NONBLOCK
  480. /* check for overflow */
  481. if (info->to_client.write_idx + sz > MEM_BUFFER_SZ) {
  482. printf("ClientMemSend overflow %d %d %d\n",
  483. info->to_client.write_idx, sz, MEM_BUFFER_SZ);
  484. osSemaphoreRelease(info->server.mutex);
  485. return -1;
  486. }
  487. #else
  488. if (info->to_server.write_idx + sz > MEM_BUFFER_SZ)
  489. sz = MEM_BUFFER_SZ - info->to_server.write_idx;
  490. #endif
  491. XMEMCPY(&info->to_server.buf[info->to_server.write_idx], buf, sz);
  492. info->to_server.write_idx += sz;
  493. info->to_server.write_bytes += sz;
  494. osSignalSet(info->server.threadId, 1);
  495. osSemaphoreRelease(info->server.mutex);
  496. #ifdef BENCH_USE_NONBLOCK
  497. if (sz == 0)
  498. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  499. #endif
  500. return sz;
  501. }
  502. /* client recv callback */
  503. static int ClientMemRecv(info_t* info, char* buf, int sz)
  504. {
  505. osSemaphoreWait(info->client.mutex, osWaitForever);
  506. #ifndef BENCH_USE_NONBLOCK
  507. while (info->to_client.write_idx - info->to_client.read_idx < sz &&
  508. !info->server.done) {
  509. osSemaphoreRelease(info->client.mutex);
  510. osSignalWait(1, osWaitForever);
  511. osSemaphoreWait(info->client.mutex, osWaitForever);
  512. }
  513. #else
  514. if (info->to_client.write_idx - info->to_client.read_idx < sz)
  515. sz = info->to_client.write_idx - info->to_client.read_idx;
  516. #endif
  517. XMEMCPY(buf, &info->to_client.buf[info->to_client.read_idx], sz);
  518. info->to_client.read_idx += sz;
  519. info->to_client.read_bytes += sz;
  520. /* if the rx has caught up with pending then reset buffer positions */
  521. if (info->to_client.read_bytes == info->to_client.write_bytes) {
  522. info->to_client.read_bytes = info->to_client.read_idx = 0;
  523. info->to_client.write_bytes = info->to_client.write_idx = 0;
  524. }
  525. osSemaphoreRelease(info->client.mutex);
  526. #ifdef BENCH_USE_NONBLOCK
  527. if (sz == 0)
  528. return WOLFSSL_CBIO_ERR_WANT_READ;
  529. #endif
  530. return sz;
  531. }
  532. static int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  533. {
  534. info_t* info = (info_t*)ctx;
  535. (void)ssl;
  536. return ServerMemSend(info, buf, sz);
  537. }
  538. static int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  539. {
  540. info_t* info = (info_t*)ctx;
  541. (void)ssl;
  542. return ServerMemRecv(info, buf, sz);
  543. }
  544. static int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  545. {
  546. info_t* info = (info_t*)ctx;
  547. (void)ssl;
  548. return ClientMemSend(info, buf, sz);
  549. }
  550. static int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  551. {
  552. info_t* info = (info_t*)ctx;
  553. (void)ssl;
  554. return ClientMemRecv(info, buf, sz);
  555. }
  556. static int bench_tls_client(info_t* info)
  557. {
  558. byte *writeBuf = NULL, *readBuf = NULL;
  559. double start, total = 0;
  560. int ret, readBufSz;
  561. WOLFSSL_CTX* cli_ctx = NULL;
  562. WOLFSSL* cli_ssl = NULL;
  563. int haveShownPeerInfo = 0;
  564. int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
  565. int total_sz;
  566. total = gettime_secs(0);
  567. /* set up client */
  568. #ifdef WOLFSSL_TLS13
  569. if (tls13)
  570. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  571. #endif
  572. if (!tls13)
  573. #if !defined(WOLFSSL_TLS13)
  574. cli_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
  575. #elif !defined(WOLFSSL_NO_TLS12)
  576. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
  577. #endif
  578. if (cli_ctx == NULL) {
  579. printf("error creating ctx\n");
  580. ret = MEMORY_E; goto exit;
  581. }
  582. #ifndef NO_CERTS
  583. #ifdef HAVE_ECC
  584. if (XSTRSTR(info->cipher, "ECDSA")) {
  585. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_ecc_cert_der_256,
  586. sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
  587. }
  588. else
  589. #endif
  590. {
  591. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_cert_der_2048,
  592. sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
  593. }
  594. if (ret != WOLFSSL_SUCCESS) {
  595. printf("error loading CA\n");
  596. goto exit;
  597. }
  598. #endif /* !NO_CERTS */
  599. wolfSSL_CTX_SetIOSend(cli_ctx, ClientSend);
  600. wolfSSL_CTX_SetIORecv(cli_ctx, ClientRecv);
  601. /* set cipher suite */
  602. ret = wolfSSL_CTX_set_cipher_list(cli_ctx, info->cipher);
  603. if (ret != WOLFSSL_SUCCESS) {
  604. printf("error setting cipher suite\n");
  605. goto exit;
  606. }
  607. #ifndef NO_DH
  608. ret = wolfSSL_CTX_SetMinDhKey_Sz(cli_ctx, MIN_DHKEY_BITS);
  609. if (ret != WOLFSSL_SUCCESS) {
  610. printf("Error setting minimum DH key size\n");
  611. goto exit;
  612. }
  613. #endif /* !NO_DH */
  614. /* Allocate and initialize a packet sized buffer */
  615. writeBuf = (unsigned char*)XMALLOC(info->packetSize, NULL,
  616. DYNAMIC_TYPE_TMP_BUFFER);
  617. if (writeBuf == NULL) {
  618. printf("failed to allocate write memory\n");
  619. ret = MEMORY_E; goto exit;
  620. }
  621. /* Allocate read buffer */
  622. readBufSz = info->packetSize;
  623. readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  624. if (readBuf == NULL) {
  625. printf("failed to allocate read memory\n");
  626. ret = MEMORY_E; goto exit;
  627. }
  628. /* BENCHMARK CONNECTIONS LOOP */
  629. while (!info->client.shutdown) {
  630. int writeSz = info->packetSize;
  631. #ifdef BENCH_USE_NONBLOCK
  632. int err;
  633. #endif
  634. cli_ssl = wolfSSL_new(cli_ctx);
  635. if (cli_ssl == NULL) {
  636. printf("error creating client object\n");
  637. goto exit;
  638. }
  639. wolfSSL_SetIOReadCtx(cli_ssl, info);
  640. wolfSSL_SetIOWriteCtx(cli_ssl, info);
  641. /* perform connect */
  642. start = gettime_secs(1);
  643. #ifndef BENCH_USE_NONBLOCK
  644. ret = wolfSSL_connect(cli_ssl);
  645. #else
  646. do
  647. {
  648. ret = wolfSSL_connect(cli_ssl);
  649. err = wolfSSL_get_error(cli_ssl, ret);
  650. }
  651. while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  652. #endif
  653. start = gettime_secs(0) - start;
  654. if (ret != WOLFSSL_SUCCESS) {
  655. ret = wolfSSL_get_error(cli_ssl, ret);
  656. printf("error %d connecting client\n", ret);
  657. goto exit;
  658. }
  659. info->client_stats.connTime += start;
  660. info->client_stats.connCount++;
  661. if ((info->showPeerInfo) && (!haveShownPeerInfo)) {
  662. haveShownPeerInfo = 1;
  663. ShowPeer(cli_ssl);
  664. }
  665. /* check for run time completion and issue shutdown */
  666. if (gettime_secs(0) - total >= info->runTimeSec) {
  667. info->client.shutdown = 1;
  668. writeSz = (int)XSTRLEN(kShutdown) + 1;
  669. XMEMCPY(writeBuf, kShutdown, writeSz); /* include null term */
  670. if (info->showVerbose) {
  671. printf("Sending shutdown\n");
  672. }
  673. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  674. if (ret < 0) {
  675. ret = wolfSSL_get_error(cli_ssl, ret);
  676. printf("error %d on client write\n", ret);
  677. goto exit;
  678. }
  679. }
  680. else {
  681. XMEMSET(writeBuf, 0, info->packetSize);
  682. XSTRNCPY((char*)writeBuf, kTestStr, info->packetSize);
  683. }
  684. /* write / read echo loop */
  685. ret = 0;
  686. total_sz = 0;
  687. while (ret == 0 && total_sz < info->maxSize && !info->client.shutdown) {
  688. /* write test message to server */
  689. start = gettime_secs(1);
  690. #ifndef BENCH_USE_NONBLOCK
  691. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  692. #else
  693. do {
  694. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  695. err = wolfSSL_get_error(cli_ssl, ret);
  696. }
  697. while (err == WOLFSSL_ERROR_WANT_WRITE);
  698. #endif
  699. info->client_stats.txTime += gettime_secs(0) - start;
  700. if (ret < 0) {
  701. ret = wolfSSL_get_error(cli_ssl, ret);
  702. printf("error %d on client write\n", ret);
  703. goto exit;
  704. }
  705. info->client_stats.txTotal += ret;
  706. total_sz += ret;
  707. /* read echo of message from server */
  708. XMEMSET(readBuf, 0, readBufSz);
  709. start = gettime_secs(1);
  710. #ifndef BENCH_USE_NONBLOCK
  711. ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
  712. #else
  713. do {
  714. ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
  715. err = wolfSSL_get_error(cli_ssl, ret);
  716. }
  717. while (err == WOLFSSL_ERROR_WANT_READ);
  718. #endif
  719. info->client_stats.rxTime += gettime_secs(0) - start;
  720. if (ret < 0) {
  721. ret = wolfSSL_get_error(cli_ssl, ret);
  722. printf("error %d on client read\n", ret);
  723. goto exit;
  724. }
  725. info->client_stats.rxTotal += ret;
  726. ret = 0; /* reset return code */
  727. /* validate echo */
  728. if (XMEMCMP((char*)writeBuf, (char*)readBuf, writeSz) != 0) {
  729. printf("echo check failed!\n");
  730. goto exit;
  731. }
  732. }
  733. wolfSSL_free(cli_ssl);
  734. cli_ssl = NULL;
  735. }
  736. exit:
  737. if (ret != 0 && ret != WOLFSSL_SUCCESS) {
  738. printf("Client Error: %d (%s)\n", ret,
  739. wolfSSL_ERR_reason_error_string(ret));
  740. }
  741. /* cleanup */
  742. if (cli_ssl != NULL)
  743. wolfSSL_free(cli_ssl);
  744. if (cli_ctx != NULL)
  745. wolfSSL_CTX_free(cli_ctx);
  746. XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  747. XFREE(writeBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  748. info->client.ret = ret;
  749. return ret;
  750. }
  751. static void client_thread(const void* args)
  752. {
  753. int ret;
  754. info_t* info = (info_t*)args;
  755. do {
  756. ret = bench_tls_client(info);
  757. /* signal server */
  758. if (!info->server.done && info->server.threadId != 0)
  759. osSignalSet(info->server.threadId, 1);
  760. info->client.ret = ret;
  761. info->client.done = 1;
  762. osThreadSuspend(NULL);
  763. if (info->doShutdown)
  764. info->client.done = 1;
  765. } while (!info->doShutdown);
  766. osThreadTerminate(info->client.threadId);
  767. }
  768. static int bench_tls_server(info_t* info)
  769. {
  770. byte *readBuf = NULL;
  771. double start;
  772. int ret, len = 0, readBufSz;
  773. WOLFSSL_CTX* srv_ctx = NULL;
  774. WOLFSSL* srv_ssl = NULL;
  775. int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
  776. int total_sz;
  777. /* set up server */
  778. #ifdef WOLFSSL_TLS13
  779. if (tls13)
  780. srv_ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
  781. #endif
  782. if (!tls13)
  783. srv_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
  784. if (srv_ctx == NULL) {
  785. printf("error creating server ctx\n");
  786. ret = MEMORY_E; goto exit;
  787. }
  788. #ifndef NO_CERTS
  789. #ifdef HAVE_ECC
  790. if (XSTRSTR(info->cipher, "ECDSA")) {
  791. ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, ecc_key_der_256,
  792. sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
  793. }
  794. else
  795. #endif
  796. {
  797. ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, server_key_der_2048,
  798. sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1);
  799. }
  800. if (ret != WOLFSSL_SUCCESS) {
  801. printf("error loading server key\n");
  802. goto exit;
  803. }
  804. #ifdef HAVE_ECC
  805. if (XSTRSTR(info->cipher, "ECDSA")) {
  806. ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, serv_ecc_der_256,
  807. sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
  808. }
  809. else
  810. #endif
  811. {
  812. ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, server_cert_der_2048,
  813. sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
  814. }
  815. if (ret != WOLFSSL_SUCCESS) {
  816. printf("error loading server cert\n");
  817. goto exit;
  818. }
  819. #endif /* !NO_CERTS */
  820. wolfSSL_CTX_SetIOSend(srv_ctx, ServerSend);
  821. wolfSSL_CTX_SetIORecv(srv_ctx, ServerRecv);
  822. /* set cipher suite */
  823. ret = wolfSSL_CTX_set_cipher_list(srv_ctx, info->cipher);
  824. if (ret != WOLFSSL_SUCCESS) {
  825. printf("error setting cipher suite\n");
  826. goto exit;
  827. }
  828. #ifndef NO_DH
  829. ret = wolfSSL_CTX_SetMinDhKey_Sz(srv_ctx, MIN_DHKEY_BITS);
  830. if (ret != WOLFSSL_SUCCESS) {
  831. printf("Error setting minimum DH key size\n");
  832. goto exit;
  833. }
  834. #endif
  835. /* Allocate read buffer */
  836. readBufSz = info->packetSize;
  837. readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  838. if (readBuf == NULL) {
  839. printf("failed to allocate read memory\n");
  840. ret = MEMORY_E; goto exit;
  841. }
  842. /* BENCHMARK CONNECTIONS LOOP */
  843. while (!info->server.shutdown) {
  844. #ifdef BENCH_USE_NONBLOCK
  845. int err;
  846. #endif
  847. #ifdef BENCH_USE_NONBLOCK
  848. if (ret == -2) {
  849. osDelay(0);
  850. continue;
  851. }
  852. #endif
  853. srv_ssl = wolfSSL_new(srv_ctx);
  854. if (srv_ssl == NULL) {
  855. printf("error creating server object\n");
  856. ret = MEMORY_E; goto exit;
  857. }
  858. wolfSSL_SetIOReadCtx(srv_ssl, info);
  859. wolfSSL_SetIOWriteCtx(srv_ssl, info);
  860. #ifndef NO_DH
  861. wolfSSL_SetTmpDH(srv_ssl, p, sizeof(p), g, sizeof(g));
  862. #endif
  863. /* accept TLS connection */
  864. start = gettime_secs(1);
  865. #ifndef BENCH_USE_NONBLOCK
  866. ret = wolfSSL_accept(srv_ssl);
  867. #else
  868. do {
  869. ret = wolfSSL_accept(srv_ssl);
  870. err = wolfSSL_get_error(srv_ssl, ret);
  871. }
  872. while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  873. #endif
  874. start = gettime_secs(0) - start;
  875. if (ret != WOLFSSL_SUCCESS) {
  876. ret = wolfSSL_get_error(srv_ssl, ret);
  877. printf("error %d on server accept\n", ret);
  878. goto exit;
  879. }
  880. info->server_stats.connTime += start;
  881. info->server_stats.connCount++;
  882. /* echo loop */
  883. ret = 0;
  884. total_sz = 0;
  885. while (ret == 0 && total_sz < info->maxSize) {
  886. double rxTime;
  887. /* read message from client */
  888. XMEMSET(readBuf, 0, readBufSz);
  889. start = gettime_secs(1);
  890. #ifndef BENCH_USE_NONBLOCK
  891. ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
  892. #else
  893. do {
  894. ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
  895. err = wolfSSL_get_error(srv_ssl, ret);
  896. }
  897. while (err == WOLFSSL_ERROR_WANT_READ);
  898. #endif
  899. rxTime = gettime_secs(0) - start;
  900. /* shutdown signals, no more connections for this cipher */
  901. if (XSTRSTR((const char*)readBuf, kShutdown) != NULL) {
  902. info->server.shutdown = 1;
  903. if (info->showVerbose) {
  904. printf("Server shutdown done\n");
  905. }
  906. ret = 0; /* success */
  907. break;
  908. }
  909. info->server_stats.rxTime += rxTime;
  910. if (ret < 0) {
  911. ret = wolfSSL_get_error(srv_ssl, ret);
  912. printf("error %d on server read\n", ret);
  913. goto exit;
  914. }
  915. info->server_stats.rxTotal += ret;
  916. len = ret;
  917. total_sz += ret;
  918. /* write message back to client */
  919. start = gettime_secs(1);
  920. #ifndef BENCH_USE_NONBLOCK
  921. ret = wolfSSL_write(srv_ssl, readBuf, len);
  922. #else
  923. do {
  924. ret = wolfSSL_write(srv_ssl, readBuf, len);
  925. err = wolfSSL_get_error(srv_ssl, ret);
  926. }
  927. while (err == WOLFSSL_ERROR_WANT_WRITE);
  928. #endif
  929. info->server_stats.txTime += gettime_secs(0) - start;
  930. if (ret < 0) {
  931. ret = wolfSSL_get_error(srv_ssl, ret);
  932. printf("error %d on server write\n", ret);
  933. goto exit;
  934. }
  935. info->server_stats.txTotal += ret;
  936. ret = 0; /* reset return code */
  937. }
  938. wolfSSL_free(srv_ssl);
  939. srv_ssl = NULL;
  940. }
  941. exit:
  942. if (ret != 0 && ret != WOLFSSL_SUCCESS) {
  943. printf("Server Error: %d (%s)\n", ret,
  944. wolfSSL_ERR_reason_error_string(ret));
  945. }
  946. /* clean up */
  947. if (srv_ssl != NULL)
  948. wolfSSL_free(srv_ssl);
  949. if (srv_ctx != NULL)
  950. wolfSSL_CTX_free(srv_ctx);
  951. XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  952. info->server.ret = ret;
  953. return ret;
  954. }
  955. static void server_thread(const void* args)
  956. {
  957. int ret;
  958. info_t* info = (info_t*)args;
  959. do {
  960. ret = bench_tls_server(info);
  961. /* signal client */
  962. if (!info->client.done && info->client.threadId != 0)
  963. osSignalSet(info->client.threadId, 1);
  964. info->server.ret = ret;
  965. info->server.done = 1;
  966. osThreadSuspend(NULL);
  967. if (info->doShutdown)
  968. info->server.done = 1;
  969. } while (!info->doShutdown);
  970. osThreadTerminate(info->server.threadId);
  971. }
  972. int bench_tls(void* args)
  973. {
  974. int ret = 0;
  975. info_t *info = NULL;
  976. char *cipher, *next_cipher, *ciphers;
  977. /* Runtime variables */
  978. int argRuntimeSec = BENCH_RUNTIME_SEC;
  979. int argTestPacketSize = TEST_PACKET_SIZE;
  980. int argTestMaxSize = TEST_MAX_SIZE;
  981. int argShowVerbose = SHOW_VERBOSE;
  982. const char* argHost = BENCH_DEFAULT_HOST;
  983. int argPort = BENCH_DEFAULT_PORT;
  984. int argShowPeerInfo = BENCH_SHOW_PEER_INFO;
  985. #ifdef DEBUG_WOLFSSL
  986. if (argShowVerbose) {
  987. wolfSSL_Debugging_ON();
  988. }
  989. else {
  990. wolfSSL_Debugging_OFF();
  991. }
  992. #endif
  993. #ifdef TEST_CIPHER_SUITE
  994. ciphers = TEST_CIPHER_SUITE;
  995. #else
  996. /* Get cipher suite list */
  997. ciphers = (char*)XMALLOC(WOLFSSL_CIPHER_LIST_MAX_SIZE, NULL,
  998. DYNAMIC_TYPE_TMP_BUFFER);
  999. if (ciphers == NULL) {
  1000. ret = MEMORY_E; goto exit;
  1001. }
  1002. wolfSSL_get_ciphers(ciphers, WOLFSSL_CIPHER_LIST_MAX_SIZE);
  1003. #endif
  1004. cipher = ciphers;
  1005. /* Allocate test info */
  1006. info = (info_t*)XMALLOC(sizeof(info_t), NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1007. if (info == NULL) {
  1008. ret = MEMORY_E; goto exit;
  1009. }
  1010. XMEMSET(info, 0, sizeof(info_t));
  1011. info->host = argHost;
  1012. info->port = argPort;
  1013. info->packetSize = argTestPacketSize;
  1014. info->runTimeSec = argRuntimeSec;
  1015. info->maxSize = argTestMaxSize;
  1016. info->showPeerInfo = argShowPeerInfo;
  1017. info->showVerbose = argShowVerbose;
  1018. info->server.mutex = osSemaphoreCreate(&info->server.mutexDef, 1);
  1019. info->client.mutex = osSemaphoreCreate(&info->client.mutexDef, 1);
  1020. /* threads */
  1021. info->server.threadDef.name = "server_thread";
  1022. info->server.threadDef.pthread = server_thread;
  1023. info->server.threadDef.tpriority = osPriorityNormal;
  1024. info->server.threadDef.stacksize = WOLF_EXAMPLES_STACK;
  1025. info->client.threadDef.name = "client_thread";
  1026. info->client.threadDef.pthread = client_thread;
  1027. info->client.threadDef.tpriority = osPriorityNormal;
  1028. info->client.threadDef.stacksize = WOLF_EXAMPLES_STACK;
  1029. /* parse by : */
  1030. while ((cipher != NULL) && (cipher[0] != '\0')) {
  1031. next_cipher = strchr(cipher, ':');
  1032. if (next_cipher != NULL) {
  1033. cipher[next_cipher - cipher] = '\0';
  1034. }
  1035. if (argShowVerbose) {
  1036. printf("Cipher: %s\n", cipher);
  1037. }
  1038. /* set cipher suite */
  1039. info->cipher = cipher;
  1040. /* reset thread info */
  1041. info->server.ret = info->client.ret = 0;
  1042. info->server.done = info->client.done = 0;
  1043. info->server.shutdown = info->client.shutdown = 0;
  1044. XMEMSET(&info->server_stats, 0, sizeof(info->server_stats));
  1045. XMEMSET(&info->client_stats, 0, sizeof(info->client_stats));
  1046. XMEMSET(&info->to_server, 0, sizeof(info->to_server));
  1047. XMEMSET(&info->to_client, 0, sizeof(info->to_client));
  1048. /* make sure nothing is locking it */
  1049. osSemaphoreRelease(info->server.mutex);
  1050. osSemaphoreRelease(info->client.mutex);
  1051. /* start threads */
  1052. if (info->server.threadId == 0) {
  1053. info->server.threadId = osThreadCreate(&info->server.threadDef, info);
  1054. }
  1055. else {
  1056. osThreadResume(info->server.threadId);
  1057. }
  1058. if (info->client.threadId == 0) {
  1059. info->client.threadId = osThreadCreate(&info->client.threadDef, info);
  1060. }
  1061. else {
  1062. osThreadResume(info->client.threadId);
  1063. }
  1064. /* Wait until threads are marked done */
  1065. while (!info->client.done || !info->server.done) {
  1066. osThreadYield(); /* Allow other threads to run */
  1067. }
  1068. if (argShowVerbose) {
  1069. /* print results */
  1070. PrintTlsStats(&info->server_stats, "Server", info->cipher, 1);
  1071. PrintTlsStats(&info->client_stats, "Client", info->cipher, 1);
  1072. }
  1073. printf("%-6s %-33s %11s %9s %9s %9s %9s %9s %17s %15s\n",
  1074. "Side", "Cipher", "Total Bytes", "Num Conns", "Rx ms", "Tx ms",
  1075. "Rx MB/s", "Tx MB/s", "Connect Total ms", "Connect Avg ms");
  1076. PrintTlsStats(&info->server_stats, "Server", info->cipher, 0);
  1077. PrintTlsStats(&info->client_stats, "Client", info->cipher, 0);
  1078. PrintMemStats();
  1079. /* target next cipher */
  1080. cipher = (next_cipher != NULL) ? (next_cipher + 1) : NULL;
  1081. } /* while */
  1082. /* do thread shutdown */
  1083. info->doShutdown = 1;
  1084. info->server.done = 0;
  1085. info->client.done = 0;
  1086. osThreadResume(info->server.threadId);
  1087. osThreadResume(info->client.threadId);
  1088. /* Wait until threads are marked done */
  1089. while (!info->client.done || !info->server.done) {
  1090. osThreadYield(); /* Allow other threads to run */
  1091. }
  1092. exit:
  1093. /* cleanup thread info */
  1094. osSemaphoreDelete(info->server.mutex);
  1095. osSemaphoreDelete(info->client.mutex);
  1096. XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1097. #ifndef TEST_CIPHER_SUITE
  1098. /* Free cipher list */
  1099. XFREE(ciphers, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1100. #endif
  1101. /* set return code */
  1102. if (args)
  1103. ((func_args*)args)->return_code = ret;
  1104. return ret;
  1105. }
  1106. #endif /* (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) && !WOLFCRYPT_ONLY */
  1107. /*****************************************************************************
  1108. * Private functions
  1109. ****************************************************************************/
  1110. /*****************************************************************************
  1111. * Public functions
  1112. ****************************************************************************/
  1113. void wolfCryptDemo(const void* argument)
  1114. {
  1115. HAL_StatusTypeDef halRet;
  1116. uint8_t buffer[1]; /* single char */
  1117. func_args args;
  1118. #ifdef DEBUG_WOLFSSL
  1119. wolfSSL_Debugging_ON();
  1120. #endif
  1121. /* initialize wolfSSL */
  1122. wolfSSL_Init();
  1123. while (1) {
  1124. memset(&args, 0, sizeof(args));
  1125. args.return_code = NOT_COMPILED_IN; /* default */
  1126. printf("\r\n\t\t\t\tMENU\r\n");
  1127. printf(menu1);
  1128. printf("Please select one of the above options:\n");
  1129. do {
  1130. halRet = HAL_UART_Receive(&huart4, buffer, sizeof(buffer), 100);
  1131. } while (halRet != HAL_OK || buffer[0] == '\n' || buffer[0] == '\r');
  1132. switch (buffer[0]) {
  1133. case 't':
  1134. printf("Running wolfCrypt Tests...\n");
  1135. #ifndef NO_CRYPT_TEST
  1136. args.return_code = 0;
  1137. wolfcrypt_test(&args);
  1138. #endif
  1139. printf("Crypt Test: Return code %d\n", args.return_code);
  1140. break;
  1141. case 'b':
  1142. printf("Running wolfCrypt Benchmarks...\n");
  1143. #ifndef NO_CRYPT_BENCHMARK
  1144. args.return_code = 0;
  1145. benchmark_test(&args);
  1146. #endif
  1147. printf("Benchmark Test: Return code %d\n", args.return_code);
  1148. break;
  1149. case 'l':
  1150. printf("Running TLS Benchmarks...\n");
  1151. #if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && !defined(WOLFCRYPT_ONLY)
  1152. bench_tls(&args);
  1153. #endif
  1154. printf("TLS Benchmarks: Return code %d\n", args.return_code);
  1155. break;
  1156. case 'e':
  1157. ShowCiphers();
  1158. break;
  1159. // All other cases go here
  1160. default:
  1161. printf("\r\nSelection out of range\r\n");
  1162. break;
  1163. }
  1164. PrintMemStats();
  1165. }
  1166. wolfSSL_Cleanup();
  1167. }