2
0

wolfssl_example.c 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955
  1. /* wolfssl_example.c
  2. *
  3. * Copyright (C) 2006-2024 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. #ifndef SINGLE_THREADED
  30. #include <cmsis_os.h>
  31. #ifdef WOLFSSL_DEBUG_MEMORY
  32. /* for memory debugging */
  33. #include <task.h>
  34. #endif
  35. #endif
  36. #include <stdio.h>
  37. #include <string.h>
  38. /*****************************************************************************
  39. * Configuration
  40. ****************************************************************************/
  41. #if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
  42. !defined(WOLFCRYPT_ONLY) && !defined(SINGLE_THREADED)
  43. #define ENABLE_TLS_BENCH
  44. #endif
  45. #if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_TLS13) && !defined(NO_TLS_UART_TEST)
  46. #define ENABLE_TLS_UART
  47. #endif
  48. /* Defaults for configuration parameters */
  49. #define BENCH_DEFAULT_HOST "localhost"
  50. #define BENCH_DEFAULT_PORT 11112
  51. #define BENCH_RUNTIME_SEC 20
  52. #define BENCH_SHOW_PEER_INFO 1
  53. #define TEST_PACKET_SIZE (2 * 1024) /* TLS packet size */
  54. #ifdef BENCH_EMBEDDED
  55. #define TEST_MAX_SIZE (4 * 1024)
  56. #else
  57. #define TEST_MAX_SIZE (32 * 1024) /* Total bytes to benchmark */
  58. #endif
  59. /* Must be large enough to handle max packet size - TLS header MAX_MSG_EXTRA + MAX DIGEST */
  60. #define MEM_BUFFER_SZ (TEST_PACKET_SIZE + 38 + WC_MAX_DIGEST_SIZE)
  61. /* make sure memory buffer size is large enough */
  62. #if MEM_BUFFER_SZ < 2048
  63. #undef MEM_BUFFER_SZ
  64. #define MEM_BUFFER_SZ 2048
  65. #endif
  66. #define SHOW_VERBOSE 0 /* 0=tab del (minimal), 1=info, 2=debug, 3=debug w/wolf logs */
  67. #ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE
  68. #define WOLFSSL_CIPHER_LIST_MAX_SIZE 2048
  69. #endif
  70. #if 0
  71. /* define this to test only a specific cipher suite(s) (colon separated) */
  72. #define TEST_CIPHER_SUITE "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
  73. #endif
  74. #if 0
  75. /* use non-blocking mode for read/write IO */
  76. #define BENCH_USE_NONBLOCK
  77. #endif
  78. #ifndef RECV_WAIT_TIMEOUT
  79. #define RECV_WAIT_TIMEOUT 10000
  80. #endif
  81. /*****************************************************************************
  82. * Private types/enumerations/variables
  83. ****************************************************************************/
  84. #ifdef WOLFSSL_STATIC_MEMORY
  85. #if 1 /* on-chip RAM */
  86. #define RAM_STATIC
  87. #else /* external RAM */
  88. /* requires .ld to be updated with ".extram" section */
  89. #define RAM_STATIC __attribute__ ((section (".extram")))
  90. #endif
  91. #define WOLF_GEN_MEM (20*1024)
  92. #define WOLF_TLS_GEN_MEM (90*1024)
  93. #define WOLF_TLS_IO_POOL_MEM (35*1024)
  94. RAM_STATIC static byte gWolfMem[WOLF_GEN_MEM];
  95. RAM_STATIC static byte gWolfCTXCli[WOLF_TLS_GEN_MEM];
  96. RAM_STATIC static byte gWolfIOCli[WOLF_TLS_IO_POOL_MEM];
  97. RAM_STATIC static byte gWolfCTXSrv[WOLF_TLS_GEN_MEM];
  98. RAM_STATIC static byte gWolfIOSrv[WOLF_TLS_IO_POOL_MEM];
  99. WOLFSSL_HEAP_HINT* HEAP_HINT = NULL;
  100. #endif /* WOLFSSL_STATIC_MEMORY */
  101. /* This sets which UART to use for the console. It is something you will have
  102. * to configure in STMCubeIDE and then change here. */
  103. #ifndef HAL_CONSOLE_UART
  104. #define HAL_CONSOLE_UART huart4
  105. #endif
  106. extern UART_HandleTypeDef HAL_CONSOLE_UART;
  107. /*****************************************************************************
  108. * Public types/enumerations/variables
  109. ****************************************************************************/
  110. typedef struct func_args {
  111. int argc;
  112. char** argv;
  113. int return_code;
  114. } func_args;
  115. const char menu1[] = "\n"
  116. "\tt. wolfCrypt Test\n"
  117. "\tb. wolfCrypt Benchmark\n"
  118. #ifdef ENABLE_TLS_BENCH
  119. "\tl. wolfSSL TLS Bench\n"
  120. #endif
  121. "\te. Show Cipher List\n"
  122. #ifdef ENABLE_TLS_UART
  123. "\ts. Run TLS 1.3 Server over UART\n"
  124. "\tc. Run TLS 1.3 Client over UART\n"
  125. #endif
  126. ;
  127. static void PrintMemStats(void);
  128. double current_time(void);
  129. #ifdef ENABLE_TLS_BENCH
  130. static const char* kShutdown = "shutdown";
  131. static const char* kTestStr =
  132. "Biodiesel cupidatat marfa, cliche aute put a bird on it incididunt elit\n"
  133. "polaroid. Sunt tattooed bespoke reprehenderit. Sint twee organic id\n"
  134. "marfa. Commodo veniam ad esse gastropub. 3 wolf moon sartorial vero,\n"
  135. "plaid delectus biodiesel squid +1 vice. Post-ironic keffiyeh leggings\n"
  136. "selfies cray fap hoodie, forage anim. Carles cupidatat shoreditch, VHS\n"
  137. "small batch meggings kogi dolore food truck bespoke gastropub.\n"
  138. "\n"
  139. "Terry richardson adipisicing actually typewriter tumblr, twee whatever\n"
  140. "four loko you probably haven't heard of them high life. Messenger bag\n"
  141. "whatever tattooed deep v mlkshk. Brooklyn pinterest assumenda chillwave\n"
  142. "et, banksy ullamco messenger bag umami pariatur direct trade forage.\n"
  143. "Typewriter culpa try-hard, pariatur sint brooklyn meggings. Gentrify\n"
  144. "food truck next level, tousled irony non semiotics PBR ethical anim cred\n"
  145. "readymade. Mumblecore brunch lomo odd future, portland organic terry\n"
  146. "richardson elit leggings adipisicing ennui raw denim banjo hella. Godard\n"
  147. "mixtape polaroid, pork belly readymade organic cray typewriter helvetica\n"
  148. "four loko whatever street art yr farm-to-table.\n"
  149. "\n"
  150. "Vinyl keytar vice tofu. Locavore you probably haven't heard of them pug\n"
  151. "pickled, hella tonx labore truffaut DIY mlkshk elit cosby sweater sint\n"
  152. "et mumblecore. Elit swag semiotics, reprehenderit DIY sartorial nisi ugh\n"
  153. "nesciunt pug pork belly wayfarers selfies delectus. Ethical hoodie\n"
  154. "seitan fingerstache kale chips. Terry richardson artisan williamsburg,\n"
  155. "eiusmod fanny pack irony tonx ennui lo-fi incididunt tofu YOLO\n"
  156. "readymade. 8-bit sed ethnic beard officia. Pour-over iphone DIY butcher,\n"
  157. "ethnic art party qui letterpress nisi proident jean shorts mlkshk\n"
  158. "locavore.\n"
  159. "\n"
  160. "Narwhal flexitarian letterpress, do gluten-free voluptate next level\n"
  161. "banh mi tonx incididunt carles DIY. Odd future nulla 8-bit beard ut\n"
  162. "cillum pickled velit, YOLO officia you probably haven't heard of them\n"
  163. "trust fund gastropub. Nisi adipisicing tattooed, Austin mlkshk 90's\n"
  164. "small batch american apparel. Put a bird on it cosby sweater before they\n"
  165. "sold out pork belly kogi hella. Street art mollit sustainable polaroid,\n"
  166. "DIY ethnic ea pug beard dreamcatcher cosby sweater magna scenester nisi.\n"
  167. "Sed pork belly skateboard mollit, labore proident eiusmod. Sriracha\n"
  168. "excepteur cosby sweater, anim deserunt laborum eu aliquip ethical et\n"
  169. "neutra PBR selvage.\n"
  170. "\n"
  171. "Raw denim pork belly truffaut, irony plaid sustainable put a bird on it\n"
  172. "next level jean shorts exercitation. Hashtag keytar whatever, nihil\n"
  173. "authentic aliquip disrupt laborum. Tattooed selfies deserunt trust fund\n"
  174. "wayfarers. 3 wolf moon synth church-key sartorial, gastropub leggings\n"
  175. "tattooed. Labore high life commodo, meggings raw denim fingerstache pug\n"
  176. "trust fund leggings seitan forage. Nostrud ullamco duis, reprehenderit\n"
  177. "incididunt flannel sustainable helvetica pork belly pug banksy you\n"
  178. "probably haven't heard of them nesciunt farm-to-table. Disrupt nostrud\n"
  179. "mollit magna, sriracha sartorial helvetica.\n"
  180. "\n"
  181. "Nulla kogi reprehenderit, skateboard sustainable duis adipisicing viral\n"
  182. "ad fanny pack salvia. Fanny pack trust fund you probably haven't heard\n"
  183. "of them YOLO vice nihil. Keffiyeh cray lo-fi pinterest cardigan aliqua,\n"
  184. "reprehenderit aute. Culpa tousled williamsburg, marfa lomo actually anim\n"
  185. "skateboard. Iphone aliqua ugh, semiotics pariatur vero readymade\n"
  186. "organic. Marfa squid nulla, in laborum disrupt laboris irure gastropub.\n"
  187. "Veniam sunt food truck leggings, sint vinyl fap.\n"
  188. "\n"
  189. "Hella dolore pork belly, truffaut carles you probably haven't heard of\n"
  190. "them PBR helvetica in sapiente. Fashion axe ugh bushwick american\n"
  191. "apparel. Fingerstache sed iphone, jean shorts blue bottle nisi bushwick\n"
  192. "flexitarian officia veniam plaid bespoke fap YOLO lo-fi. Blog\n"
  193. "letterpress mumblecore, food truck id cray brooklyn cillum ad sed.\n"
  194. "Assumenda chambray wayfarers vinyl mixtape sustainable. VHS vinyl\n"
  195. "delectus, culpa williamsburg polaroid cliche swag church-key synth kogi\n"
  196. "magna pop-up literally. Swag thundercats ennui shoreditch vegan\n"
  197. "pitchfork neutra truffaut etsy, sed single-origin coffee craft beer.\n"
  198. "\n"
  199. "Odio letterpress brooklyn elit. Nulla single-origin coffee in occaecat\n"
  200. "meggings. Irony meggings 8-bit, chillwave lo-fi adipisicing cred\n"
  201. "dreamcatcher veniam. Put a bird on it irony umami, trust fund bushwick\n"
  202. "locavore kale chips. Sriracha swag thundercats, chillwave disrupt\n"
  203. "tousled beard mollit mustache leggings portland next level. Nihil esse\n"
  204. "est, skateboard art party etsy thundercats sed dreamcatcher ut iphone\n"
  205. "swag consectetur et. Irure skateboard banjo, nulla deserunt messenger\n"
  206. "bag dolor terry richardson sapiente.\n";
  207. #if !defined(NO_DH)
  208. #define MIN_DHKEY_BITS 1024
  209. /* dh2048 p */
  210. static const unsigned char p[] =
  211. {
  212. 0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba, 0x59, 0x06, 0x3c, 0xbc, 0x30,
  213. 0xd5, 0xf5, 0x00, 0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6, 0x25, 0x27,
  214. 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a, 0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84,
  215. 0xbf, 0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a, 0xc5, 0xbe, 0x72, 0x5c,
  216. 0xa7, 0xe7, 0x91, 0xe6, 0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48, 0xc7,
  217. 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d, 0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46,
  218. 0x3e, 0x19, 0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f, 0x2b, 0x96, 0x17,
  219. 0x39, 0x6d, 0x30, 0x8d, 0x2a, 0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
  220. 0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04, 0x83, 0x57, 0x30, 0xfb, 0xda,
  221. 0x76, 0x93, 0x38, 0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5, 0xb7, 0xc8,
  222. 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e, 0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e,
  223. 0x5a, 0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc, 0x16, 0x30, 0xdb, 0x0c,
  224. 0xfc, 0xc5, 0x62, 0xa7, 0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36, 0xf6,
  225. 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90, 0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3,
  226. 0x1a, 0xc3, 0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48, 0x4e, 0x22, 0x73,
  227. 0x6f, 0xc3, 0x5f, 0xd4, 0x9a, 0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
  228. 0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b, 0xa6, 0xb9, 0xcd, 0x29, 0xbf,
  229. 0x68, 0x1f, 0x08, 0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6, 0x06, 0x65,
  230. 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b, 0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7,
  231. 0xfa, 0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x93
  232. };
  233. /* dh2048 g */
  234. static const unsigned char g[] =
  235. {
  236. 0x02,
  237. };
  238. #endif /* !NO_DH */
  239. typedef struct {
  240. unsigned char buf[MEM_BUFFER_SZ];
  241. int write_bytes;
  242. int write_idx;
  243. int read_bytes;
  244. int read_idx;
  245. } memBuf_t;
  246. typedef struct {
  247. double connTime;
  248. double rxTime;
  249. double txTime;
  250. int connCount;
  251. int rxTotal;
  252. int txTotal;
  253. } stats_t;
  254. typedef struct {
  255. int ret;
  256. osThreadId_t threadId;
  257. #ifdef CMSIS_OS2_H_
  258. osSemaphoreId_t mutex;
  259. #else
  260. osThreadDef_t threadDef;
  261. osSemaphoreDef_t mutexDef;
  262. osSemaphoreId mutex;
  263. #endif
  264. byte shutdown:1;
  265. byte done:1;
  266. } side_t;
  267. typedef struct {
  268. const char* cipher;
  269. const char* host;
  270. word32 port;
  271. int packetSize; /* The data payload size in the packet */
  272. int maxSize;
  273. int runTimeSec;
  274. int showPeerInfo;
  275. int showVerbose;
  276. int doShutdown;
  277. side_t client;
  278. side_t server;
  279. /* client messages to server in memory */
  280. memBuf_t to_server;
  281. /* server messages to client in memory */
  282. memBuf_t to_client;
  283. /* server */
  284. stats_t server_stats;
  285. /* client */
  286. stats_t client_stats;
  287. } info_t;
  288. /*****************************************************************************
  289. * Private functions
  290. ****************************************************************************/
  291. static double gettime_secs(int reset)
  292. {
  293. return current_time();
  294. }
  295. static void PrintTlsStats(stats_t* wcStat, const char* desc, const char* cipher, int verbose)
  296. {
  297. const char* formatStr;
  298. if (verbose) {
  299. formatStr = "wolfSSL %s Benchmark on %s:\n"
  300. "\tTotal : %9d bytes\n"
  301. "\tNum Conns : %9d\n"
  302. "\tRx Total : %9.3f ms\n"
  303. "\tTx Total : %9.3f ms\n"
  304. "\tRx : %9.3f MB/s\n"
  305. "\tTx : %9.3f MB/s\n"
  306. "\tConnect : %9.3f ms\n"
  307. "\tConnect Avg : %9.3f ms\n";
  308. }
  309. else {
  310. formatStr = "%-6s %-33s %11d %9d %9.3f %9.3f %9.3f %9.3f %17.3f %15.3f\n";
  311. }
  312. printf(formatStr,
  313. desc,
  314. cipher,
  315. wcStat->txTotal + wcStat->rxTotal,
  316. wcStat->connCount,
  317. wcStat->rxTime * 1000,
  318. wcStat->txTime * 1000,
  319. wcStat->rxTotal / wcStat->rxTime / 1024 / 1024,
  320. wcStat->txTotal / wcStat->txTime / 1024 / 1024,
  321. wcStat->connTime * 1000,
  322. wcStat->connTime * 1000 / wcStat->connCount);
  323. }
  324. #endif /* ENABLE_TLS_BENCH */
  325. #if defined(ENABLE_TLS_BENCH) || defined(ENABLE_TLS_UART)
  326. #if defined(KEEP_PEER_CERT) || defined(KEEP_OUR_CERT)
  327. static const char* client_showx509_msg[] = {
  328. "issuer",
  329. "subject",
  330. "altname",
  331. "serial number",
  332. NULL
  333. };
  334. static void ShowX509(WOLFSSL_X509* x509, const char* hdr)
  335. {
  336. char* altName;
  337. char* issuer;
  338. char* subject;
  339. byte serial[32];
  340. int ret;
  341. int sz = sizeof(serial);
  342. const char** words = client_showx509_msg;
  343. if (x509 == NULL) {
  344. printf("%s No Cert\n", hdr);
  345. return;
  346. }
  347. issuer = wolfSSL_X509_NAME_oneline(
  348. wolfSSL_X509_get_issuer_name(x509), 0, 0);
  349. subject = wolfSSL_X509_NAME_oneline(
  350. wolfSSL_X509_get_subject_name(x509), 0, 0);
  351. printf("%s\n %s : %s\n %s: %s\n", hdr, words[0], issuer, words[1], subject);
  352. while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
  353. printf(" %s = %s\n", words[2], altName);
  354. ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
  355. if (ret == WOLFSSL_SUCCESS) {
  356. int i;
  357. int strLen;
  358. char serialMsg[80];
  359. /* testsuite has multiple threads writing to stdout, get output
  360. message ready to write once */
  361. strLen = sprintf(serialMsg, " %s", words[3]);
  362. for (i = 0; i < sz; i++)
  363. sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
  364. printf("%s\n", serialMsg);
  365. }
  366. XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
  367. XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
  368. #if defined(OPENSSL_EXTRA)
  369. {
  370. WOLFSSL_BIO* bio;
  371. char buf[256]; /* should be size of ASN_NAME_MAX */
  372. int textSz;
  373. /* print out domain component if certificate has it */
  374. textSz = wolfSSL_X509_NAME_get_text_by_NID(
  375. wolfSSL_X509_get_subject_name(x509), NID_domainComponent,
  376. buf, sizeof(buf));
  377. if (textSz > 0) {
  378. printf("Domain Component = %s\n", buf);
  379. }
  380. bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
  381. if (bio != NULL) {
  382. wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
  383. wolfSSL_X509_print(bio, x509);
  384. wolfSSL_BIO_free(bio);
  385. }
  386. }
  387. #endif /* OPENSSL_EXTRA */
  388. }
  389. #endif /* KEEP_PEER_CERT || KEEP_OUR_CERT */
  390. static const char* client_showpeer_msg[] = {
  391. "SSL version is",
  392. "SSL cipher suite is",
  393. "SSL curve name is",
  394. "SSL DH size is",
  395. "SSL reused session",
  396. "Alternate cert chain used",
  397. "peer's cert info:",
  398. NULL
  399. };
  400. static void ShowPeer(WOLFSSL* ssl)
  401. {
  402. WOLFSSL_CIPHER* cipher;
  403. const char** words = client_showpeer_msg;
  404. #if defined(HAVE_ECC) || !defined(NO_DH)
  405. const char *name;
  406. #endif
  407. #ifndef NO_DH
  408. int bits;
  409. #endif
  410. #ifdef KEEP_PEER_CERT
  411. WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
  412. if (peer)
  413. ShowX509(peer, words[6]);
  414. else
  415. printf("peer has no cert!\n");
  416. wolfSSL_FreeX509(peer);
  417. #endif
  418. #if defined(KEEP_OUR_CERT) && \
  419. (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
  420. ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
  421. printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
  422. #endif /* SHOW_CERTS && KEEP_OUR_CERT */
  423. printf("%s %s\n", words[0], wolfSSL_get_version(ssl));
  424. cipher = wolfSSL_get_current_cipher(ssl);
  425. printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher));
  426. #if defined(HAVE_ECC) || !defined(NO_DH)
  427. if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
  428. printf("%s %s\n", words[2], name);
  429. #endif
  430. #ifndef NO_DH
  431. else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
  432. printf("%s %d bits\n", words[3], bits);
  433. #endif
  434. if (wolfSSL_session_reused(ssl))
  435. printf("%s\n", words[4]);
  436. #ifdef WOLFSSL_ALT_CERT_CHAINS
  437. if (wolfSSL_is_peer_alt_cert_chain(ssl))
  438. printf("%s\n", words[5]);
  439. #endif
  440. (void)ssl;
  441. }
  442. #endif /* ENABLE_TLS_BENCH || ENABLE_TLS_UART */
  443. #ifdef ENABLE_TLS_BENCH
  444. /* server send callback */
  445. static int ServerMemSend(info_t* info, char* buf, int sz)
  446. {
  447. #ifdef CMSIS_OS2_H_
  448. osSemaphoreAcquire(info->client.mutex, osWaitForever);
  449. #else
  450. osSemaphoreWait(info->client.mutex, osWaitForever);
  451. #endif
  452. #ifndef BENCH_USE_NONBLOCK
  453. /* check for overflow */
  454. if (info->to_client.write_idx + sz > MEM_BUFFER_SZ) {
  455. osSemaphoreRelease(info->client.mutex);
  456. printf("ServerMemSend overflow\n");
  457. return -1;
  458. }
  459. #else
  460. if (info->to_client.write_idx + sz > MEM_BUFFER_SZ)
  461. sz = MEM_BUFFER_SZ - info->to_client.write_idx;
  462. #endif
  463. if (info->showVerbose >= 2)
  464. printf("Server Send: %d\n", sz);
  465. XMEMCPY(&info->to_client.buf[info->to_client.write_idx], buf, sz);
  466. info->to_client.write_idx += sz;
  467. info->to_client.write_bytes += sz;
  468. #ifdef CMSIS_OS2_H_
  469. osThreadFlagsSet(info->client.threadId, 1);
  470. #else
  471. osSignalSet(info->client.threadId, 1);
  472. #endif
  473. osSemaphoreRelease(info->client.mutex);
  474. #ifdef BENCH_USE_NONBLOCK
  475. if (sz == 0)
  476. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  477. #endif
  478. return sz;
  479. }
  480. /* server recv callback */
  481. static int ServerMemRecv(info_t* info, char* buf, int sz)
  482. {
  483. #ifdef CMSIS_OS2_H_
  484. osSemaphoreAcquire(info->server.mutex, osWaitForever);
  485. #else
  486. osSemaphoreWait(info->server.mutex, osWaitForever);
  487. #endif
  488. #ifndef BENCH_USE_NONBLOCK
  489. while (info->to_server.write_idx - info->to_server.read_idx < sz &&
  490. !info->client.done) {
  491. osSemaphoreRelease(info->server.mutex);
  492. #ifdef CMSIS_OS2_H_
  493. if (osThreadFlagsWait(1, osFlagsWaitAny, RECV_WAIT_TIMEOUT) == osFlagsErrorTimeout) {
  494. printf("Server Recv: Timeout!\n");
  495. return WOLFSSL_CBIO_ERR_TIMEOUT;
  496. }
  497. osSemaphoreAcquire(info->server.mutex, osWaitForever);
  498. #else
  499. if (osSignalWait(1, RECV_WAIT_TIMEOUT).status == osEventTimeout) {
  500. printf("Server Recv: Timeout!\n");
  501. return WOLFSSL_CBIO_ERR_TIMEOUT;
  502. }
  503. osSemaphoreWait(info->server.mutex, osWaitForever);
  504. #endif
  505. }
  506. #else
  507. if (info->to_server.write_idx - info->to_server.read_idx < sz)
  508. sz = info->to_server.write_idx - info->to_server.read_idx;
  509. #endif
  510. XMEMCPY(buf, &info->to_server.buf[info->to_server.read_idx], sz);
  511. info->to_server.read_idx += sz;
  512. info->to_server.read_bytes += sz;
  513. /* if the rx has caught up with pending then reset buffer positions */
  514. if (info->to_server.read_bytes == info->to_server.write_bytes) {
  515. info->to_server.read_bytes = info->to_server.read_idx = 0;
  516. info->to_server.write_bytes = info->to_server.write_idx = 0;
  517. }
  518. if (info->showVerbose >= 2)
  519. printf("Server Recv: %d\n", sz);
  520. osSemaphoreRelease(info->server.mutex);
  521. #ifdef BENCH_USE_NONBLOCK
  522. if (sz == 0)
  523. return WOLFSSL_CBIO_ERR_WANT_READ;
  524. #endif
  525. return sz;
  526. }
  527. /* client send callback */
  528. static int ClientMemSend(info_t* info, char* buf, int sz)
  529. {
  530. #ifdef CMSIS_OS2_H_
  531. osSemaphoreAcquire(info->server.mutex, osWaitForever);
  532. #else
  533. osSemaphoreWait(info->server.mutex, osWaitForever);
  534. #endif
  535. #ifndef BENCH_USE_NONBLOCK
  536. /* check for overflow */
  537. if (info->to_server.write_idx + sz > MEM_BUFFER_SZ) {
  538. printf("ClientMemSend overflow %d %d %d\n",
  539. info->to_server.write_idx, sz, MEM_BUFFER_SZ);
  540. osSemaphoreRelease(info->server.mutex);
  541. return -1;
  542. }
  543. #else
  544. if (info->to_server.write_idx + sz > MEM_BUFFER_SZ)
  545. sz = MEM_BUFFER_SZ - info->to_server.write_idx;
  546. #endif
  547. if (info->showVerbose >= 2)
  548. printf("Client Send: %d\n", sz);
  549. XMEMCPY(&info->to_server.buf[info->to_server.write_idx], buf, sz);
  550. info->to_server.write_idx += sz;
  551. info->to_server.write_bytes += sz;
  552. #ifdef CMSIS_OS2_H_
  553. osThreadFlagsSet(info->server.threadId, 1);
  554. #else
  555. osSignalSet(info->server.threadId, 1);
  556. #endif
  557. osSemaphoreRelease(info->server.mutex);
  558. #ifdef BENCH_USE_NONBLOCK
  559. if (sz == 0)
  560. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  561. #endif
  562. return sz;
  563. }
  564. /* client recv callback */
  565. static int ClientMemRecv(info_t* info, char* buf, int sz)
  566. {
  567. #ifdef CMSIS_OS2_H_
  568. osSemaphoreAcquire(info->client.mutex, osWaitForever);
  569. #else
  570. osSemaphoreWait(info->client.mutex, osWaitForever);
  571. #endif
  572. #ifndef BENCH_USE_NONBLOCK
  573. while (info->to_client.write_idx - info->to_client.read_idx < sz &&
  574. !info->server.done) {
  575. osSemaphoreRelease(info->client.mutex);
  576. #ifdef CMSIS_OS2_H_
  577. if (osThreadFlagsWait(1, osFlagsWaitAny, RECV_WAIT_TIMEOUT) == osFlagsErrorTimeout) {
  578. printf("Client Recv: Timeout!\n");
  579. return WOLFSSL_CBIO_ERR_TIMEOUT;
  580. }
  581. osSemaphoreAcquire(info->client.mutex, osWaitForever);
  582. #else
  583. if (osSignalWait(1, RECV_WAIT_TIMEOUT).status == osEventTimeout) {
  584. printf("Client Recv: Timeout!\n");
  585. return WOLFSSL_CBIO_ERR_TIMEOUT;
  586. }
  587. osSemaphoreWait(info->client.mutex, osWaitForever);
  588. #endif
  589. }
  590. #else
  591. if (info->to_client.write_idx - info->to_client.read_idx < sz)
  592. sz = info->to_client.write_idx - info->to_client.read_idx;
  593. #endif
  594. XMEMCPY(buf, &info->to_client.buf[info->to_client.read_idx], sz);
  595. info->to_client.read_idx += sz;
  596. info->to_client.read_bytes += sz;
  597. /* if the rx has caught up with pending then reset buffer positions */
  598. if (info->to_client.read_bytes == info->to_client.write_bytes) {
  599. info->to_client.read_bytes = info->to_client.read_idx = 0;
  600. info->to_client.write_bytes = info->to_client.write_idx = 0;
  601. }
  602. if (info->showVerbose >= 2)
  603. printf("Client Recv: %d\n", sz);
  604. osSemaphoreRelease(info->client.mutex);
  605. #ifdef BENCH_USE_NONBLOCK
  606. if (sz == 0)
  607. return WOLFSSL_CBIO_ERR_WANT_READ;
  608. #endif
  609. return sz;
  610. }
  611. static int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  612. {
  613. info_t* info = (info_t*)ctx;
  614. (void)ssl;
  615. return ServerMemSend(info, buf, sz);
  616. }
  617. static int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  618. {
  619. info_t* info = (info_t*)ctx;
  620. (void)ssl;
  621. return ServerMemRecv(info, buf, sz);
  622. }
  623. static int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  624. {
  625. info_t* info = (info_t*)ctx;
  626. (void)ssl;
  627. return ClientMemSend(info, buf, sz);
  628. }
  629. static int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  630. {
  631. info_t* info = (info_t*)ctx;
  632. (void)ssl;
  633. return ClientMemRecv(info, buf, sz);
  634. }
  635. static int bench_tls_client(info_t* info)
  636. {
  637. byte *writeBuf = NULL, *readBuf = NULL;
  638. double start, total = 0;
  639. int ret = 0, readBufSz;
  640. WOLFSSL_CTX* cli_ctx = NULL;
  641. WOLFSSL* cli_ssl = NULL;
  642. int haveShownPeerInfo = 0;
  643. int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
  644. int total_sz;
  645. total = gettime_secs(0);
  646. /* set up client */
  647. #ifdef WOLFSSL_TLS13
  648. if (tls13) {
  649. #ifdef WOLFSSL_STATIC_MEMORY
  650. ret = wolfSSL_CTX_load_static_memory(&cli_ctx, wolfTLSv1_3_client_method_ex,
  651. gWolfCTXCli, sizeof(gWolfCTXCli), WOLFMEM_GENERAL , 10);
  652. #else
  653. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  654. #endif
  655. }
  656. #endif
  657. if (!tls13) {
  658. #if !defined(WOLFSSL_TLS13)
  659. #ifdef WOLFSSL_STATIC_MEMORY
  660. ret = wolfSSL_CTX_load_static_memory(&cli_ctx, wolfSSLv23_client_method_ex,
  661. gWolfCTXCli, sizeof(gWolfCTXCli), WOLFMEM_GENERAL , 10);
  662. #else
  663. cli_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
  664. #endif
  665. #elif !defined(WOLFSSL_NO_TLS12)
  666. #ifdef WOLFSSL_STATIC_MEMORY
  667. ret = wolfSSL_CTX_load_static_memory(&cli_ctx, wolfTLSv1_2_client_method_ex,
  668. gWolfCTXCli, sizeof(gWolfCTXCli), WOLFMEM_GENERAL , 10);
  669. #else
  670. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
  671. #endif
  672. #endif
  673. }
  674. if (cli_ctx == NULL || ret != 0) {
  675. printf("error creating ctx: ret %d\n", ret);
  676. ret = MEMORY_E; goto exit;
  677. }
  678. #ifdef WOLFSSL_STATIC_MEMORY
  679. ret = wolfSSL_CTX_load_static_memory(&cli_ctx, 0, gWolfIOCli, sizeof(gWolfIOCli),
  680. WOLFMEM_IO_POOL, 10 );
  681. #endif
  682. #ifndef NO_CERTS
  683. #ifdef HAVE_ECC
  684. if (XSTRSTR(info->cipher, "ECDSA")) {
  685. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_ecc_cert_der_256,
  686. sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
  687. }
  688. else
  689. #endif
  690. {
  691. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_cert_der_2048,
  692. sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
  693. }
  694. if (ret != WOLFSSL_SUCCESS) {
  695. printf("error loading CA\n");
  696. goto exit;
  697. }
  698. #endif /* !NO_CERTS */
  699. wolfSSL_CTX_SetIOSend(cli_ctx, ClientSend);
  700. wolfSSL_CTX_SetIORecv(cli_ctx, ClientRecv);
  701. /* set cipher suite */
  702. ret = wolfSSL_CTX_set_cipher_list(cli_ctx, info->cipher);
  703. if (ret != WOLFSSL_SUCCESS) {
  704. printf("error setting cipher suite\n");
  705. goto exit;
  706. }
  707. #ifndef NO_DH
  708. ret = wolfSSL_CTX_SetMinDhKey_Sz(cli_ctx, MIN_DHKEY_BITS);
  709. if (ret != WOLFSSL_SUCCESS) {
  710. printf("Error setting minimum DH key size\n");
  711. goto exit;
  712. }
  713. #endif /* !NO_DH */
  714. /* Allocate and initialize a packet sized buffer */
  715. writeBuf = (unsigned char*)XMALLOC(info->packetSize, NULL,
  716. DYNAMIC_TYPE_TMP_BUFFER);
  717. if (writeBuf == NULL) {
  718. printf("failed to allocate write memory\n");
  719. ret = MEMORY_E; goto exit;
  720. }
  721. /* Allocate read buffer */
  722. readBufSz = info->packetSize;
  723. readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  724. if (readBuf == NULL) {
  725. printf("failed to allocate read memory\n");
  726. ret = MEMORY_E; goto exit;
  727. }
  728. /* BENCHMARK CONNECTIONS LOOP */
  729. while (!info->client.shutdown) {
  730. int writeSz = info->packetSize;
  731. #ifdef BENCH_USE_NONBLOCK
  732. int err;
  733. #endif
  734. cli_ssl = wolfSSL_new(cli_ctx);
  735. if (cli_ssl == NULL) {
  736. printf("error creating client object\n");
  737. ret = MEMORY_E; goto exit;
  738. }
  739. wolfSSL_SetIOReadCtx(cli_ssl, info);
  740. wolfSSL_SetIOWriteCtx(cli_ssl, info);
  741. /* perform connect */
  742. start = gettime_secs(1);
  743. #ifndef BENCH_USE_NONBLOCK
  744. ret = wolfSSL_connect(cli_ssl);
  745. #else
  746. do
  747. {
  748. ret = wolfSSL_connect(cli_ssl);
  749. err = wolfSSL_get_error(cli_ssl, ret);
  750. }
  751. while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  752. #endif
  753. start = gettime_secs(0) - start;
  754. if (ret != WOLFSSL_SUCCESS) {
  755. ret = wolfSSL_get_error(cli_ssl, ret);
  756. printf("error %d connecting client\n", ret);
  757. goto exit;
  758. }
  759. info->client_stats.connTime += start;
  760. info->client_stats.connCount++;
  761. if ((info->showPeerInfo) && (!haveShownPeerInfo)) {
  762. haveShownPeerInfo = 1;
  763. ShowPeer(cli_ssl);
  764. }
  765. /* check for run time completion and issue shutdown */
  766. if (gettime_secs(0) - total >= info->runTimeSec) {
  767. info->client.shutdown = 1;
  768. writeSz = (int)XSTRLEN(kShutdown) + 1;
  769. XMEMCPY(writeBuf, kShutdown, writeSz); /* include null term */
  770. if (info->showVerbose) {
  771. printf("Sending shutdown\n");
  772. }
  773. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  774. if (ret < 0) {
  775. ret = wolfSSL_get_error(cli_ssl, ret);
  776. printf("error %d on client write\n", ret);
  777. goto exit;
  778. }
  779. }
  780. else {
  781. XMEMSET(writeBuf, 0, info->packetSize);
  782. XSTRNCPY((char*)writeBuf, kTestStr, info->packetSize);
  783. }
  784. /* write / read echo loop */
  785. ret = 0;
  786. total_sz = 0;
  787. while (ret == 0 && total_sz < info->maxSize && !info->client.shutdown) {
  788. /* write test message to server */
  789. start = gettime_secs(1);
  790. #ifndef BENCH_USE_NONBLOCK
  791. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  792. #else
  793. do {
  794. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  795. err = wolfSSL_get_error(cli_ssl, ret);
  796. }
  797. while (err == WOLFSSL_ERROR_WANT_WRITE);
  798. #endif
  799. info->client_stats.txTime += gettime_secs(0) - start;
  800. if (ret < 0) {
  801. ret = wolfSSL_get_error(cli_ssl, ret);
  802. printf("error %d on client write\n", ret);
  803. goto exit;
  804. }
  805. info->client_stats.txTotal += ret;
  806. total_sz += ret;
  807. /* read echo of message from server */
  808. XMEMSET(readBuf, 0, readBufSz);
  809. start = gettime_secs(1);
  810. #ifndef BENCH_USE_NONBLOCK
  811. ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
  812. #else
  813. do {
  814. ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
  815. err = wolfSSL_get_error(cli_ssl, ret);
  816. }
  817. while (err == WOLFSSL_ERROR_WANT_READ);
  818. #endif
  819. info->client_stats.rxTime += gettime_secs(0) - start;
  820. if (ret < 0) {
  821. ret = wolfSSL_get_error(cli_ssl, ret);
  822. printf("error %d on client read\n", ret);
  823. goto exit;
  824. }
  825. info->client_stats.rxTotal += ret;
  826. ret = 0; /* reset return code */
  827. /* validate echo */
  828. if (XMEMCMP((char*)writeBuf, (char*)readBuf, writeSz) != 0) {
  829. printf("echo check failed!\n");
  830. goto exit;
  831. }
  832. }
  833. wolfSSL_free(cli_ssl);
  834. cli_ssl = NULL;
  835. }
  836. exit:
  837. if (ret != 0 && ret != WOLFSSL_SUCCESS) {
  838. info->doShutdown = 1;
  839. printf("Client Error: %d (%s)\n", ret,
  840. wolfSSL_ERR_reason_error_string(ret));
  841. }
  842. /* cleanup */
  843. if (cli_ssl != NULL)
  844. wolfSSL_free(cli_ssl);
  845. if (cli_ctx != NULL)
  846. wolfSSL_CTX_free(cli_ctx);
  847. XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  848. XFREE(writeBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  849. info->client.ret = ret;
  850. return ret;
  851. }
  852. #ifdef CMSIS_OS2_H_
  853. static void client_thread(void* args)
  854. #else
  855. static void client_thread(const void* args)
  856. #endif
  857. {
  858. int ret;
  859. info_t* info = (info_t*)args;
  860. #ifdef CMSIS_OS2_H_
  861. info->client.threadId = osThreadGetId();
  862. #endif
  863. do {
  864. ret = bench_tls_client(info);
  865. /* signal server */
  866. if (!info->server.done && info->server.threadId != 0) {
  867. #ifdef CMSIS_OS2_H_
  868. osThreadFlagsSet(info->server.threadId, 1);
  869. #else
  870. osSignalSet(info->server.threadId, 1);
  871. #endif
  872. }
  873. info->client.ret = ret;
  874. info->client.done = 1;
  875. osThreadSuspend(info->client.threadId);
  876. if (info->doShutdown)
  877. info->server.done = 1;
  878. } while (!info->doShutdown);
  879. osThreadTerminate(info->client.threadId);
  880. info->client.threadId = NULL;
  881. }
  882. static int bench_tls_server(info_t* info)
  883. {
  884. byte *readBuf = NULL;
  885. double start;
  886. int ret = 0, len = 0, readBufSz;
  887. WOLFSSL_CTX* srv_ctx = NULL;
  888. WOLFSSL* srv_ssl = NULL;
  889. int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
  890. int total_sz;
  891. /* set up server */
  892. #ifdef WOLFSSL_TLS13
  893. if (tls13) {
  894. #ifdef WOLFSSL_STATIC_MEMORY
  895. ret = wolfSSL_CTX_load_static_memory(&srv_ctx, wolfTLSv1_3_server_method_ex,
  896. gWolfCTXSrv, sizeof(gWolfCTXSrv), WOLFMEM_GENERAL , 10);
  897. #else
  898. srv_ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
  899. #endif
  900. }
  901. #endif
  902. if (!tls13) {
  903. #if !defined(WOLFSSL_TLS13)
  904. #ifdef WOLFSSL_STATIC_MEMORY
  905. ret = wolfSSL_CTX_load_static_memory(&srv_ctx, wolfSSLv23_server_method_ex,
  906. gWolfCTXSrv, sizeof(gWolfCTXSrv), WOLFMEM_GENERAL , 10);
  907. #else
  908. srv_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
  909. #endif
  910. #elif !defined(WOLFSSL_NO_TLS12)
  911. #ifdef WOLFSSL_STATIC_MEMORY
  912. ret = wolfSSL_CTX_load_static_memory(&srv_ctx, wolfTLSv1_2_server_method_ex,
  913. gWolfCTXSrv, sizeof(gWolfCTXSrv), WOLFMEM_GENERAL , 10);
  914. #else
  915. srv_ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
  916. #endif
  917. #endif
  918. }
  919. if (srv_ctx == NULL || ret != 0) {
  920. printf("error creating server ctx: ret %d\n", ret);
  921. ret = MEMORY_E; goto exit;
  922. }
  923. #ifdef WOLFSSL_STATIC_MEMORY
  924. ret = wolfSSL_CTX_load_static_memory(&srv_ctx, 0, gWolfIOSrv, sizeof(gWolfIOSrv),
  925. WOLFMEM_IO_POOL, 10 );
  926. #endif
  927. #ifndef NO_CERTS
  928. #ifdef HAVE_ECC
  929. if (XSTRSTR(info->cipher, "ECDSA")) {
  930. ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, ecc_key_der_256,
  931. sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
  932. }
  933. else
  934. #endif
  935. {
  936. ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, server_key_der_2048,
  937. sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1);
  938. }
  939. if (ret != WOLFSSL_SUCCESS) {
  940. printf("error loading server key\n");
  941. goto exit;
  942. }
  943. #ifdef HAVE_ECC
  944. if (XSTRSTR(info->cipher, "ECDSA")) {
  945. ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, serv_ecc_der_256,
  946. sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
  947. }
  948. else
  949. #endif
  950. {
  951. ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, server_cert_der_2048,
  952. sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
  953. }
  954. if (ret != WOLFSSL_SUCCESS) {
  955. printf("error loading server cert\n");
  956. goto exit;
  957. }
  958. #endif /* !NO_CERTS */
  959. wolfSSL_CTX_SetIOSend(srv_ctx, ServerSend);
  960. wolfSSL_CTX_SetIORecv(srv_ctx, ServerRecv);
  961. /* set cipher suite */
  962. ret = wolfSSL_CTX_set_cipher_list(srv_ctx, info->cipher);
  963. if (ret != WOLFSSL_SUCCESS) {
  964. printf("error setting cipher suite\n");
  965. goto exit;
  966. }
  967. #ifndef NO_DH
  968. ret = wolfSSL_CTX_SetMinDhKey_Sz(srv_ctx, MIN_DHKEY_BITS);
  969. if (ret != WOLFSSL_SUCCESS) {
  970. printf("Error setting minimum DH key size\n");
  971. goto exit;
  972. }
  973. #endif
  974. /* Allocate read buffer */
  975. readBufSz = info->packetSize;
  976. readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  977. if (readBuf == NULL) {
  978. printf("failed to allocate read memory\n");
  979. ret = MEMORY_E; goto exit;
  980. }
  981. /* BENCHMARK CONNECTIONS LOOP */
  982. while (!info->server.shutdown) {
  983. #ifdef BENCH_USE_NONBLOCK
  984. int err;
  985. #endif
  986. #ifdef BENCH_USE_NONBLOCK
  987. if (ret == -2) {
  988. osDelay(0);
  989. continue;
  990. }
  991. #endif
  992. srv_ssl = wolfSSL_new(srv_ctx);
  993. if (srv_ssl == NULL) {
  994. printf("error creating server object\n");
  995. ret = MEMORY_E; goto exit;
  996. }
  997. wolfSSL_SetIOReadCtx(srv_ssl, info);
  998. wolfSSL_SetIOWriteCtx(srv_ssl, info);
  999. #ifndef NO_DH
  1000. wolfSSL_SetTmpDH(srv_ssl, p, sizeof(p), g, sizeof(g));
  1001. #endif
  1002. /* accept TLS connection */
  1003. start = gettime_secs(1);
  1004. #ifndef BENCH_USE_NONBLOCK
  1005. ret = wolfSSL_accept(srv_ssl);
  1006. #else
  1007. do {
  1008. ret = wolfSSL_accept(srv_ssl);
  1009. err = wolfSSL_get_error(srv_ssl, ret);
  1010. }
  1011. while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1012. #endif
  1013. start = gettime_secs(0) - start;
  1014. if (ret != WOLFSSL_SUCCESS) {
  1015. ret = wolfSSL_get_error(srv_ssl, ret);
  1016. printf("error %d on server accept\n", ret);
  1017. goto exit;
  1018. }
  1019. info->server_stats.connTime += start;
  1020. info->server_stats.connCount++;
  1021. /* echo loop */
  1022. ret = 0;
  1023. total_sz = 0;
  1024. while (ret == 0 && total_sz < info->maxSize) {
  1025. double rxTime;
  1026. /* read message from client */
  1027. XMEMSET(readBuf, 0, readBufSz);
  1028. start = gettime_secs(1);
  1029. #ifndef BENCH_USE_NONBLOCK
  1030. ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
  1031. #else
  1032. do {
  1033. ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
  1034. err = wolfSSL_get_error(srv_ssl, ret);
  1035. }
  1036. while (err == WOLFSSL_ERROR_WANT_READ);
  1037. #endif
  1038. rxTime = gettime_secs(0) - start;
  1039. /* shutdown signals, no more connections for this cipher */
  1040. if (XSTRSTR((const char*)readBuf, kShutdown) != NULL) {
  1041. info->server.shutdown = 1;
  1042. if (info->showVerbose) {
  1043. printf("Server shutdown done\n");
  1044. }
  1045. ret = 0; /* success */
  1046. break;
  1047. }
  1048. info->server_stats.rxTime += rxTime;
  1049. if (ret < 0) {
  1050. ret = wolfSSL_get_error(srv_ssl, ret);
  1051. printf("error %d on server read\n", ret);
  1052. goto exit;
  1053. }
  1054. info->server_stats.rxTotal += ret;
  1055. len = ret;
  1056. total_sz += ret;
  1057. /* write message back to client */
  1058. start = gettime_secs(1);
  1059. #ifndef BENCH_USE_NONBLOCK
  1060. ret = wolfSSL_write(srv_ssl, readBuf, len);
  1061. #else
  1062. do {
  1063. ret = wolfSSL_write(srv_ssl, readBuf, len);
  1064. err = wolfSSL_get_error(srv_ssl, ret);
  1065. }
  1066. while (err == WOLFSSL_ERROR_WANT_WRITE);
  1067. #endif
  1068. info->server_stats.txTime += gettime_secs(0) - start;
  1069. if (ret < 0) {
  1070. ret = wolfSSL_get_error(srv_ssl, ret);
  1071. printf("error %d on server write\n", ret);
  1072. goto exit;
  1073. }
  1074. info->server_stats.txTotal += ret;
  1075. ret = 0; /* reset return code */
  1076. }
  1077. wolfSSL_free(srv_ssl);
  1078. srv_ssl = NULL;
  1079. }
  1080. exit:
  1081. if (ret != 0 && ret != WOLFSSL_SUCCESS) {
  1082. info->doShutdown = 1;
  1083. printf("Server Error: %d (%s)\n", ret,
  1084. wolfSSL_ERR_reason_error_string(ret));
  1085. }
  1086. /* clean up */
  1087. if (srv_ssl != NULL)
  1088. wolfSSL_free(srv_ssl);
  1089. if (srv_ctx != NULL)
  1090. wolfSSL_CTX_free(srv_ctx);
  1091. XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1092. info->server.ret = ret;
  1093. return ret;
  1094. }
  1095. #ifdef CMSIS_OS2_H_
  1096. static void server_thread(void* args)
  1097. #else
  1098. static void server_thread(const void* args)
  1099. #endif
  1100. {
  1101. int ret;
  1102. info_t* info = (info_t*)args;
  1103. #ifdef CMSIS_OS2_H_
  1104. info->server.threadId = osThreadGetId();
  1105. #endif
  1106. do {
  1107. ret = bench_tls_server(info);
  1108. /* signal client */
  1109. if (!info->client.done && info->client.threadId != 0) {
  1110. #ifdef CMSIS_OS2_H_
  1111. osThreadFlagsSet(info->client.threadId, 1);
  1112. #else
  1113. osSignalSet(info->client.threadId, 1);
  1114. #endif
  1115. }
  1116. info->server.ret = ret;
  1117. info->server.done = 1;
  1118. osThreadSuspend(info->server.threadId);
  1119. if (info->doShutdown)
  1120. info->client.done = 1;
  1121. } while (!info->doShutdown);
  1122. osThreadTerminate(info->server.threadId);
  1123. info->server.threadId = NULL;
  1124. }
  1125. #ifdef CMSIS_OS2_H_
  1126. static const osThreadAttr_t server_thread_attributes = {
  1127. .name = "server_thread",
  1128. .priority = (osPriority_t) osPriorityNormal,
  1129. .stack_size = WOLF_EXAMPLES_STACK
  1130. };
  1131. static const osThreadAttr_t client_thread_attributes = {
  1132. .name = "client_thread",
  1133. .priority = (osPriority_t) osPriorityNormal,
  1134. .stack_size = WOLF_EXAMPLES_STACK
  1135. };
  1136. #endif
  1137. int bench_tls(void* args)
  1138. {
  1139. int ret = 0;
  1140. info_t *info = NULL;
  1141. char *cipher, *next_cipher, *ciphers;
  1142. /* Runtime variables */
  1143. int argRuntimeSec = BENCH_RUNTIME_SEC;
  1144. int argTestPacketSize = TEST_PACKET_SIZE;
  1145. int argTestMaxSize = TEST_MAX_SIZE;
  1146. int argShowVerbose = SHOW_VERBOSE;
  1147. const char* argHost = BENCH_DEFAULT_HOST;
  1148. int argPort = BENCH_DEFAULT_PORT;
  1149. int argShowPeerInfo = BENCH_SHOW_PEER_INFO;
  1150. #ifdef DEBUG_WOLFSSL
  1151. if (argShowVerbose >= 3) {
  1152. wolfSSL_Debugging_ON();
  1153. }
  1154. else {
  1155. wolfSSL_Debugging_OFF();
  1156. }
  1157. #endif
  1158. #ifdef TEST_CIPHER_SUITE
  1159. ciphers = TEST_CIPHER_SUITE;
  1160. #else
  1161. /* Get cipher suite list */
  1162. ciphers = (char*)XMALLOC(WOLFSSL_CIPHER_LIST_MAX_SIZE, NULL,
  1163. DYNAMIC_TYPE_TMP_BUFFER);
  1164. if (ciphers == NULL) {
  1165. ret = MEMORY_E; goto exit;
  1166. }
  1167. wolfSSL_get_ciphers(ciphers, WOLFSSL_CIPHER_LIST_MAX_SIZE);
  1168. #endif
  1169. cipher = ciphers;
  1170. /* Allocate test info */
  1171. info = (info_t*)XMALLOC(sizeof(info_t), NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1172. if (info == NULL) {
  1173. ret = MEMORY_E; goto exit;
  1174. }
  1175. XMEMSET(info, 0, sizeof(info_t));
  1176. info->host = argHost;
  1177. info->port = argPort;
  1178. info->packetSize = argTestPacketSize;
  1179. info->runTimeSec = argRuntimeSec;
  1180. info->maxSize = argTestMaxSize;
  1181. info->showPeerInfo = argShowPeerInfo;
  1182. info->showVerbose = argShowVerbose;
  1183. #ifdef CMSIS_OS2_H_
  1184. info->server.mutex = osSemaphoreNew(1, 0, NULL);
  1185. info->client.mutex = osSemaphoreNew(1, 0, NULL);
  1186. #else
  1187. info->server.mutex = osSemaphoreCreate(&info->server.mutexDef, 1);
  1188. info->client.mutex = osSemaphoreCreate(&info->client.mutexDef, 1);
  1189. /* threads */
  1190. info->server.threadDef.name = "server_thread";
  1191. info->server.threadDef.pthread = server_thread;
  1192. info->server.threadDef.tpriority = osPriorityNormal;
  1193. info->server.threadDef.stacksize = WOLF_EXAMPLES_STACK;
  1194. info->client.threadDef.name = "client_thread";
  1195. info->client.threadDef.pthread = client_thread;
  1196. info->client.threadDef.tpriority = osPriorityNormal;
  1197. info->client.threadDef.stacksize = WOLF_EXAMPLES_STACK;
  1198. #endif
  1199. /* parse by : */
  1200. while ((cipher != NULL) && (cipher[0] != '\0')) {
  1201. next_cipher = strchr(cipher, ':');
  1202. if (next_cipher != NULL) {
  1203. cipher[next_cipher - cipher] = '\0';
  1204. }
  1205. if (argShowVerbose) {
  1206. printf("Cipher: %s\n", cipher);
  1207. }
  1208. /* set cipher suite */
  1209. info->cipher = cipher;
  1210. /* reset thread info */
  1211. info->server.ret = info->client.ret = 0;
  1212. info->server.done = info->client.done = 0;
  1213. info->server.shutdown = info->client.shutdown = 0;
  1214. XMEMSET(&info->server_stats, 0, sizeof(info->server_stats));
  1215. XMEMSET(&info->client_stats, 0, sizeof(info->client_stats));
  1216. XMEMSET(&info->to_server, 0, sizeof(info->to_server));
  1217. XMEMSET(&info->to_client, 0, sizeof(info->to_client));
  1218. /* make sure nothing is locking it */
  1219. osSemaphoreRelease(info->server.mutex);
  1220. osSemaphoreRelease(info->client.mutex);
  1221. /* start threads */
  1222. if (info->server.threadId == 0) {
  1223. #ifdef CMSIS_OS2_H_
  1224. osThreadNew(server_thread, info, &server_thread_attributes);
  1225. #else
  1226. info->server.threadId = osThreadCreate(&info->server.threadDef, info);
  1227. #endif
  1228. }
  1229. else {
  1230. osThreadResume(info->server.threadId);
  1231. }
  1232. if (info->client.threadId == 0) {
  1233. #ifdef CMSIS_OS2_H_
  1234. osThreadNew(client_thread, info, &client_thread_attributes);
  1235. #else
  1236. info->client.threadId = osThreadCreate(&info->client.threadDef, info);
  1237. #endif
  1238. }
  1239. else {
  1240. osThreadResume(info->client.threadId);
  1241. }
  1242. /* Wait until threads are marked done */
  1243. while (!info->client.done || !info->server.done) {
  1244. osThreadYield(); /* Allow other threads to run */
  1245. }
  1246. if (argShowVerbose) {
  1247. /* print results */
  1248. PrintTlsStats(&info->server_stats, "Server", info->cipher, 1);
  1249. PrintTlsStats(&info->client_stats, "Client", info->cipher, 1);
  1250. }
  1251. printf("%-6s %-33s %11s %9s %9s %9s %9s %9s %17s %15s\n",
  1252. "Side", "Cipher", "Total Bytes", "Num Conns", "Rx ms", "Tx ms",
  1253. "Rx MB/s", "Tx MB/s", "Connect Total ms", "Connect Avg ms");
  1254. PrintTlsStats(&info->server_stats, "Server", info->cipher, 0);
  1255. PrintTlsStats(&info->client_stats, "Client", info->cipher, 0);
  1256. PrintMemStats();
  1257. /* target next cipher */
  1258. cipher = (next_cipher != NULL) ? (next_cipher + 1) : NULL;
  1259. } /* while */
  1260. /* do thread shutdown */
  1261. info->doShutdown = 1;
  1262. info->server.done = 0;
  1263. info->client.done = 0;
  1264. osThreadResume(info->server.threadId);
  1265. osThreadResume(info->client.threadId);
  1266. /* Wait until threads are marked done */
  1267. while (!info->client.done || !info->server.done) {
  1268. osThreadYield(); /* Allow other threads to run */
  1269. }
  1270. exit:
  1271. /* cleanup thread info */
  1272. osSemaphoreDelete(info->server.mutex);
  1273. osSemaphoreDelete(info->client.mutex);
  1274. XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1275. #ifndef TEST_CIPHER_SUITE
  1276. /* Free cipher list */
  1277. XFREE(ciphers, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1278. #endif
  1279. /* set return code */
  1280. if (args)
  1281. ((func_args*)args)->return_code = ret;
  1282. return ret;
  1283. }
  1284. #endif /* ENABLE_TLS_BENCH */
  1285. #ifndef WOLFCRYPT_ONLY
  1286. static void ShowCiphers(void)
  1287. {
  1288. int ret;
  1289. char* ciphers = (char*)XMALLOC(WOLFSSL_CIPHER_LIST_MAX_SIZE, NULL,
  1290. DYNAMIC_TYPE_TMP_BUFFER);
  1291. if (ciphers) {
  1292. ret = wolfSSL_get_ciphers(ciphers, WOLFSSL_CIPHER_LIST_MAX_SIZE);
  1293. if (ret == WOLFSSL_SUCCESS)
  1294. printf("%s\n", ciphers);
  1295. XFREE(ciphers, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1296. }
  1297. }
  1298. #endif
  1299. static void PrintMemStats(void)
  1300. {
  1301. #ifdef WOLFSSL_DEBUG_MEMORY
  1302. printf("\nHeap MinEver %d, Free %d, Stack %lu\n",
  1303. xPortGetMinimumEverFreeHeapSize(),
  1304. xPortGetFreeHeapSize(),
  1305. uxTaskGetStackHighWaterMark(NULL));
  1306. #endif
  1307. }
  1308. #ifdef ENABLE_TLS_UART
  1309. /* UART DMA IO Routines */
  1310. #ifndef B115200
  1311. #define B115200 115200
  1312. #endif
  1313. /* Max buffer for a single TLS frame */
  1314. #ifndef MAX_RECORD_SIZE
  1315. #define MAX_RECORD_SIZE (16 * 1024)
  1316. #endif
  1317. typedef struct {
  1318. int curr_index;
  1319. int data_len;
  1320. char buf[MAX_RECORD_SIZE];
  1321. } tls13_buf;
  1322. /* This sets which UART to do the TLS 1.3 connection over. It is something you
  1323. * will have to configure in STMCubeIDE and then change here. */
  1324. #ifndef TLS_UART
  1325. #define TLS_UART huart2
  1326. #endif
  1327. /* If you get an undefined error here you can optionally disable the TLS
  1328. * over UART test using NO_TLS_UART_TEST */
  1329. extern UART_HandleTypeDef TLS_UART;
  1330. static int msg_length = 0;
  1331. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
  1332. if (huart->Instance == TLS_UART.Instance) {
  1333. msg_length = Size;
  1334. }
  1335. }
  1336. static int uartIORx(WOLFSSL *ssl, char *buf, int sz, void *ctx)
  1337. {
  1338. HAL_StatusTypeDef status;
  1339. tls13_buf *tb = ctx;
  1340. #ifdef DEBUG_UART_IO
  1341. printf("UART Read: In %d\n", sz);
  1342. #endif
  1343. if (tb->curr_index + sz <= tb->data_len) {
  1344. XMEMCPY(buf, tb->buf + tb->curr_index, sz);
  1345. tb->curr_index += sz;
  1346. #ifdef DEBUG_UART_IO
  1347. printf("UART Read1: Out %d\n", sz);
  1348. #endif
  1349. return sz;
  1350. }
  1351. msg_length = 0;
  1352. XMEMSET(tb, 0, sizeof(*tb));
  1353. /* Now setup the DMA RX */
  1354. /* This requires enabling the UART RX DMA in the STM32Cube tool
  1355. * Under Connectivity click on your TLS UART (USART2) and goto DMA Settings
  1356. * and Add one for USART2_RX with default options */
  1357. status = HAL_UARTEx_ReceiveToIdle_DMA(&TLS_UART, (uint8_t *)tb->buf, MAX_RECORD_SIZE);
  1358. if (status != HAL_OK) {
  1359. return WOLFSSL_CBIO_ERR_WANT_READ;
  1360. }
  1361. else {
  1362. /* We now go into an infinite loop waiting for msg_length to be set to a
  1363. * value other than 0. This will be done when the other side writes to
  1364. * UART and then idles. That will trigger HAL_UARTEx_RxEventCallback()
  1365. * which will set msg_length to the length of data written.
  1366. *
  1367. * If you mistakenly get stuck here, please simply reset the board.
  1368. */
  1369. while (msg_length == 0) {
  1370. HAL_Delay(10);
  1371. }
  1372. #ifdef DEBUG_UART_IO
  1373. printf("Message received! length = %d\n", msg_length);
  1374. #endif
  1375. }
  1376. /* now return the number of bytes requested. */
  1377. XMEMCPY(buf, tb->buf, sz);
  1378. tb->data_len = msg_length;
  1379. tb->curr_index = sz;
  1380. #ifdef DEBUG_UART_IO
  1381. printf("UART Read2: Out %d\n", tb->data_len);
  1382. #endif
  1383. return sz;
  1384. }
  1385. static int uartIOTx(WOLFSSL *ssl, char *buf, int sz, void *ctx)
  1386. {
  1387. HAL_StatusTypeDef status;
  1388. int ret = sz;
  1389. (void)ctx;
  1390. #ifdef DEBUG_UART_IO
  1391. printf("UART Write: In %d\n", sz);
  1392. #endif
  1393. status = HAL_UART_Transmit(&TLS_UART, (uint8_t *)buf, sz, 0xFFFF);
  1394. if (status != HAL_OK) {
  1395. ret = WOLFSSL_CBIO_ERR_WANT_WRITE;
  1396. }
  1397. #ifdef DEBUG_UART_IO
  1398. printf("UART Write: Out %d\n", ret);
  1399. #endif
  1400. return ret;
  1401. }
  1402. static void uartReset(void)
  1403. {
  1404. HAL_UART_Abort_IT(&TLS_UART);
  1405. }
  1406. /* UART TLS 1.3 client and server */
  1407. #ifndef NO_WOLFSSL_SERVER
  1408. static int tls13_uart_server(void)
  1409. {
  1410. int ret = -1, err;
  1411. WOLFSSL_CTX* ctx = NULL;
  1412. WOLFSSL* ssl = NULL;
  1413. byte echoBuffer[100];
  1414. #ifdef WOLFSSL_SMALL_STACK
  1415. tls13_buf* tbuf = (tls13_buf*)XMALLOC(sizeof(*tbuf), NULL,
  1416. DYNAMIC_TYPE_TMP_BUFFER);
  1417. if (tbuf == NULL) {
  1418. printf("Memory allocation error\n");
  1419. goto done;
  1420. }
  1421. #else
  1422. tls13_buf tbuf[1];
  1423. #endif
  1424. XMEMSET(tbuf, 0, sizeof(tls13_buf));
  1425. ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
  1426. if (ctx == NULL) {
  1427. printf("Error creating WOLFSSL_CTX\n");
  1428. goto done;
  1429. }
  1430. /* Register wolfSSL send/recv callbacks */
  1431. uartReset();
  1432. wolfSSL_CTX_SetIOSend(ctx, uartIOTx);
  1433. wolfSSL_CTX_SetIORecv(ctx, uartIORx);
  1434. ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, ecc_key_der_256,
  1435. sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
  1436. if (ret != WOLFSSL_SUCCESS) {
  1437. printf("error loading server private key\n");
  1438. goto done;
  1439. }
  1440. ret = wolfSSL_CTX_use_certificate_buffer(ctx, serv_ecc_der_256,
  1441. sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
  1442. if (ret != WOLFSSL_SUCCESS) {
  1443. printf("error loading server certificate\n");
  1444. goto done;
  1445. }
  1446. ssl = wolfSSL_new(ctx);
  1447. if (ssl == NULL) {
  1448. printf("Error creating WOLFSSL\n");
  1449. goto done;
  1450. }
  1451. wolfSSL_SetIOReadCtx(ssl, tbuf);
  1452. printf("Waiting for client\n");
  1453. do {
  1454. ret = wolfSSL_accept(ssl);
  1455. err = wolfSSL_get_error(ssl, ret);
  1456. } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1457. if (ret != WOLFSSL_SUCCESS) {
  1458. printf("TLS accept error %d\n", err);
  1459. goto done;
  1460. }
  1461. printf("TLS Accept handshake done\n");
  1462. /* Waiting for data to echo */
  1463. XMEMSET(echoBuffer, 0, sizeof(echoBuffer));
  1464. do {
  1465. ret = wolfSSL_read(ssl, echoBuffer, sizeof(echoBuffer)-1);
  1466. err = wolfSSL_get_error(ssl, ret);
  1467. } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1468. printf("Read (%d): %s\n", err, echoBuffer);
  1469. do {
  1470. ret = wolfSSL_write(ssl, echoBuffer, XSTRLEN((char*)echoBuffer));
  1471. err = wolfSSL_get_error(ssl, ret);
  1472. } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1473. printf("Sent (%d): %s\n", err, echoBuffer);
  1474. ret = 0; /* Success */
  1475. done:
  1476. if (ssl) {
  1477. wolfSSL_shutdown(ssl);
  1478. wolfSSL_free(ssl);
  1479. }
  1480. if (ctx) {
  1481. wolfSSL_CTX_free(ctx);
  1482. }
  1483. #ifdef WOLFSSL_SMALL_STACK
  1484. XFREE(tbuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1485. #endif
  1486. return ret;
  1487. }
  1488. #endif
  1489. #ifdef ENABLE_TLS_UART
  1490. static int tls13_uart_client(void)
  1491. {
  1492. int ret = -1, err;
  1493. WOLFSSL_CTX* ctx = NULL;
  1494. WOLFSSL* ssl = NULL;
  1495. const char testStr[] = "Testing 1, 2 and 3\r\n";
  1496. byte readBuf[100];
  1497. #ifdef WOLFSSL_SMALL_STACK
  1498. tls13_buf* tbuf = (tls13_buf*)XMALLOC(sizeof(*tbuf), NULL,
  1499. DYNAMIC_TYPE_TMP_BUFFER);
  1500. if (tbuf == NULL) {
  1501. printf("Memory allocation error\n");
  1502. goto done;
  1503. }
  1504. #else
  1505. tls13_buf tbuf[1];
  1506. #endif
  1507. XMEMSET(tbuf, 0, sizeof(tls13_buf));
  1508. ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  1509. if (ctx == NULL) {
  1510. printf("Error creating WOLFSSL_CTX\n");
  1511. goto done;
  1512. }
  1513. /* Register wolfSSL send/recv callbacks */
  1514. uartReset();
  1515. wolfSSL_CTX_SetIOSend(ctx, uartIOTx);
  1516. wolfSSL_CTX_SetIORecv(ctx, uartIORx);
  1517. /* Load the root certificate. */
  1518. wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
  1519. ssl = wolfSSL_new(ctx);
  1520. if (ssl == NULL) {
  1521. printf("Error creating WOLFSSL\n");
  1522. goto done;
  1523. }
  1524. wolfSSL_SetIOReadCtx(ssl, tbuf);
  1525. #ifdef WOLFSSL_HAVE_KYBER
  1526. #ifndef WOLFSSL_NO_ML_KEM
  1527. if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ML_KEM_512) != WOLFSSL_SUCCESS) {
  1528. printf("wolfSSL_UseKeyShare Error!!");
  1529. }
  1530. #else
  1531. if (wolfSSL_UseKeyShare(ssl, WOLFSSL_KYBER_LEVEL1) != WOLFSSL_SUCCESS) {
  1532. printf("wolfSSL_UseKeyShare Error!!");
  1533. }
  1534. #endif
  1535. #endif
  1536. do {
  1537. ret = wolfSSL_connect(ssl);
  1538. err = wolfSSL_get_error(ssl, ret);
  1539. } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1540. if (ret != WOLFSSL_SUCCESS) {
  1541. printf("TLS connect error %d\n", err);
  1542. goto done;
  1543. }
  1544. ShowPeer(ssl);
  1545. printf("TLS Connect handshake done\n");
  1546. printf("Sending test string\n");
  1547. do {
  1548. ret = wolfSSL_write(ssl, testStr, XSTRLEN(testStr));
  1549. err = wolfSSL_get_error(ssl, ret);
  1550. } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1551. printf("Sent (%d): %s\n", err, testStr);
  1552. XMEMSET(readBuf, 0, sizeof(readBuf));
  1553. do {
  1554. ret = wolfSSL_read(ssl, readBuf, sizeof(readBuf)-1);
  1555. err = wolfSSL_get_error(ssl, ret);
  1556. } while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1557. printf("Read (%d): %s\n", err, readBuf);
  1558. ret = 0; /* Success */
  1559. done:
  1560. if (ssl) {
  1561. wolfSSL_shutdown(ssl);
  1562. wolfSSL_free(ssl);
  1563. }
  1564. if (ctx) {
  1565. wolfSSL_CTX_free(ctx);
  1566. }
  1567. #ifdef WOLFSSL_SMALL_STACK
  1568. XFREE(tbuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1569. #endif
  1570. return ret;
  1571. }
  1572. #endif
  1573. #endif /* ENABLE_TLS_UART */
  1574. /*****************************************************************************
  1575. * Public functions
  1576. ****************************************************************************/
  1577. #ifdef HAL_RTC_MODULE_ENABLED
  1578. extern RTC_HandleTypeDef hrtc;
  1579. double current_time(void)
  1580. {
  1581. RTC_TimeTypeDef time;
  1582. RTC_DateTypeDef date;
  1583. uint32_t subsec = 0;
  1584. /* must get time and date here due to STM32 HW bug */
  1585. HAL_RTC_GetTime(&hrtc, &time, FORMAT_BIN);
  1586. HAL_RTC_GetDate(&hrtc, &date, FORMAT_BIN);
  1587. /* Not all STM32 RTCs have subseconds in the struct */
  1588. #ifdef RTC_ALARMSUBSECONDMASK_ALL
  1589. subsec = (255 - time.SubSeconds) * 1000 / 255;
  1590. #endif
  1591. (void) date;
  1592. /* return seconds.milliseconds */
  1593. return ((double) time.Hours * 24) + ((double) time.Minutes * 60)
  1594. + (double) time.Seconds + ((double) subsec / 1000);
  1595. }
  1596. #endif /* HAL_RTC_MODULE_ENABLED */
  1597. #ifdef CMSIS_OS2_H_
  1598. void wolfCryptDemo(void* argument)
  1599. #else
  1600. void wolfCryptDemo(const void* argument)
  1601. #endif
  1602. {
  1603. HAL_StatusTypeDef halRet;
  1604. uint8_t buffer[2];
  1605. func_args args;
  1606. #if 0
  1607. wolfSSL_Debugging_ON();
  1608. #endif
  1609. /* initialize wolfSSL */
  1610. #ifdef WOLFCRYPT_ONLY
  1611. wolfCrypt_Init();
  1612. #else
  1613. wolfSSL_Init();
  1614. #endif
  1615. #ifdef WOLFSSL_STATIC_MEMORY
  1616. if (wc_LoadStaticMemory(&HEAP_HINT, gWolfMem, sizeof(gWolfMem),
  1617. WOLFMEM_GENERAL, 10) != 0) {
  1618. printf("unable to load static memory");
  1619. }
  1620. #endif
  1621. //wolfSSL_SetAllocators(wolfMallocCb, wolfFreeCb, wolfReallocCb);
  1622. while (1) {
  1623. memset(&args, 0, sizeof(args));
  1624. args.return_code = NOT_COMPILED_IN; /* default */
  1625. printf("\n\t\t\t\tMENU\n");
  1626. printf(menu1);
  1627. printf("Please select one of the above options:\n");
  1628. do {
  1629. halRet = HAL_UART_Receive(&HAL_CONSOLE_UART, buffer, sizeof(buffer), 100);
  1630. } while (halRet != HAL_OK || buffer[0] == '\n' || buffer[0] == '\r');
  1631. switch (buffer[0]) {
  1632. case 't':
  1633. printf("Running wolfCrypt Tests...\n");
  1634. #ifndef NO_CRYPT_TEST
  1635. args.return_code = 0;
  1636. wolfcrypt_test(&args);
  1637. #else
  1638. args.return_code = NOT_COMPILED_IN;
  1639. #endif
  1640. printf("Crypt Test: Return code %d\n", args.return_code);
  1641. break;
  1642. case 'b':
  1643. printf("Running wolfCrypt Benchmarks...\n");
  1644. #ifndef NO_CRYPT_BENCHMARK
  1645. args.return_code = 0;
  1646. benchmark_test(&args);
  1647. #else
  1648. args.return_code = NOT_COMPILED_IN;
  1649. #endif
  1650. printf("Benchmark Test: Return code %d\n", args.return_code);
  1651. break;
  1652. case 'l':
  1653. printf("Running TLS Benchmarks...\n");
  1654. #ifdef ENABLE_TLS_BENCH
  1655. bench_tls(&args);
  1656. #else
  1657. args.return_code = NOT_COMPILED_IN;
  1658. #endif
  1659. printf("TLS Benchmarks: Return code %d\n", args.return_code);
  1660. break;
  1661. case 'e':
  1662. #ifndef WOLFCRYPT_ONLY
  1663. ShowCiphers();
  1664. #else
  1665. printf("Not compiled in\n");
  1666. #endif
  1667. break;
  1668. #ifdef ENABLE_TLS_UART
  1669. case 's':
  1670. #ifndef NO_WOLFSSL_SERVER
  1671. printf("Running TLS 1.3 server...\n");
  1672. args.return_code = tls13_uart_server();
  1673. #else
  1674. args.return_code = NOT_COMPILED_IN;
  1675. #endif
  1676. printf("TLS 1.3 Server: Return code %d\n", args.return_code);
  1677. break;
  1678. case 'c':
  1679. #ifndef NO_WOLFSSL_CLIENT
  1680. printf("Running TLS 1.3 client...\n");
  1681. args.return_code = tls13_uart_client();
  1682. #else
  1683. args.return_code = NOT_COMPILED_IN;
  1684. #endif
  1685. printf("TLS 1.3 Client: Return code %d\n", args.return_code);
  1686. break;
  1687. #endif /* ENABLE_TLS_UART */
  1688. /* All other cases go here */
  1689. default:
  1690. printf("\nSelection out of range\n");
  1691. break;
  1692. }
  1693. PrintMemStats();
  1694. }
  1695. #ifdef WOLFCRYPT_ONLY
  1696. wolfCrypt_Cleanup();
  1697. #else
  1698. wolfSSL_Cleanup();
  1699. #endif
  1700. }