testsuite.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. /* testsuite.c
  2. *
  3. * Copyright (C) 2006-2023 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. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #include <wolfssl/wolfcrypt/types.h>
  26. #include <wolfssl/ssl.h>
  27. #include <wolfssl/test.h>
  28. #include <wolfcrypt/test/test.h>
  29. #ifndef SINGLE_THREADED
  30. #ifdef OPENSSL_EXTRA
  31. #include <wolfssl/openssl/ssl.h>
  32. #endif
  33. #include <wolfssl/wolfcrypt/sha256.h>
  34. #include <wolfssl/wolfcrypt/ecc.h>
  35. #include <examples/echoclient/echoclient.h>
  36. #include <examples/echoserver/echoserver.h>
  37. #include <examples/server/server.h>
  38. #include <examples/client/client.h>
  39. #define WOLFSSL_TEST_UTILS_INCLUDED
  40. #include "tests/utils.c"
  41. #ifndef NO_SHA256
  42. void file_test(const char* file, byte* check);
  43. #endif
  44. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT)
  45. #ifdef HAVE_STACK_SIZE
  46. static THREAD_RETURN simple_test(func_args *args);
  47. #else
  48. static void simple_test(func_args *args);
  49. #endif
  50. static int test_tls(func_args* server_args);
  51. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
  52. defined(HAVE_CRL) && defined(HAVE_CRL_MONITOR)
  53. static int test_crl_monitor(void);
  54. #endif
  55. static void show_ciphers(void);
  56. static void cleanup_output(void);
  57. static int validate_cleanup_output(void);
  58. enum {
  59. NUMARGS = 3
  60. };
  61. static const char *outputName;
  62. #endif
  63. int myoptind = 0;
  64. char* myoptarg = NULL;
  65. #ifndef NO_TESTSUITE_MAIN_DRIVER
  66. static int testsuite_test(int argc, char** argv);
  67. int main(int argc, char** argv)
  68. {
  69. return testsuite_test(argc, argv);
  70. }
  71. #endif /* NO_TESTSUITE_MAIN_DRIVER */
  72. #ifdef HAVE_STACK_SIZE
  73. /* Wrap TLS echo client to free thread locals. */
  74. static void *echoclient_test_wrapper(void* args) {
  75. echoclient_test(args);
  76. #if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
  77. wc_ecc_fp_free(); /* free per thread cache */
  78. #endif
  79. return (void *)0;
  80. }
  81. #endif
  82. int testsuite_test(int argc, char** argv)
  83. {
  84. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
  85. (!defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLF_CRYPTO_CB_ONLY_ECC))
  86. func_args server_args;
  87. tcp_ready ready;
  88. #if !defined(NETOS)
  89. THREAD_TYPE serverThread;
  90. int ret;
  91. #endif
  92. #ifndef USE_WINDOWS_API
  93. const char *tempDir = NULL;
  94. char tempName[128];
  95. int tempName_len;
  96. int tempName_Xnum;
  97. #else
  98. char tempName[] = "fnXXXXXX";
  99. const int tempName_len = 8;
  100. const int tempName_Xnum = 6;
  101. #endif
  102. #ifdef HAVE_STACK_SIZE
  103. void *serverThreadStackContext = NULL;
  104. #endif
  105. #ifndef USE_WINDOWS_API
  106. #ifdef XGETENV
  107. tempDir = XGETENV("TMPDIR");
  108. if (tempDir == NULL)
  109. #endif
  110. {
  111. tempDir = "/tmp";
  112. }
  113. XSTRLCPY(tempName, tempDir, sizeof(tempName));
  114. XSTRLCAT(tempName, "/testsuite-output-XXXXXX", sizeof(tempName));
  115. tempName_len = (int)XSTRLEN(tempName);
  116. tempName_Xnum = 6;
  117. #endif /* !USE_WINDOWS_API */
  118. #ifdef HAVE_WNR
  119. if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0) {
  120. err_sys("Whitewood netRandom global config failed");
  121. return -1237;
  122. }
  123. #endif /* HAVE_WNR */
  124. StartTCP();
  125. server_args.argc = argc;
  126. server_args.argv = argv;
  127. wolfSSL_Init();
  128. #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND)
  129. wolfSSL_Debugging_ON();
  130. #endif
  131. #if !defined(WOLFSSL_TIRTOS)
  132. ChangeToWolfRoot();
  133. #endif
  134. #ifdef WOLFSSL_TIRTOS
  135. fdOpenSession(Task_self());
  136. #endif
  137. server_args.signal = &ready;
  138. InitTcpReady(&ready);
  139. #ifndef NO_CRYPT_TEST
  140. /* wc_ test */
  141. #ifdef HAVE_STACK_SIZE
  142. StackSizeCheck(&server_args, wolfcrypt_test);
  143. #else
  144. wolfcrypt_test(&server_args);
  145. #endif
  146. if (server_args.return_code != 0) return server_args.return_code;
  147. #endif
  148. /* Simple wolfSSL client server test */
  149. #ifdef HAVE_STACK_SIZE
  150. StackSizeCheck(&server_args, (THREAD_RETURN (*)(void *))simple_test);
  151. #else
  152. simple_test(&server_args);
  153. #endif
  154. if (server_args.return_code != 0) return server_args.return_code;
  155. #if !defined(NETOS)
  156. /* Echo input wolfSSL client server test */
  157. #ifdef HAVE_STACK_SIZE
  158. StackSizeCheck_launch(&server_args, echoserver_test, &serverThread,
  159. &serverThreadStackContext);
  160. #else
  161. start_thread(echoserver_test, &server_args, &serverThread);
  162. #endif
  163. /* Create unique file name */
  164. outputName = mymktemp(tempName, tempName_len, tempName_Xnum);
  165. if (outputName == NULL) {
  166. printf("Could not create unique file name");
  167. return EXIT_FAILURE;
  168. }
  169. ret = test_tls(&server_args);
  170. if (ret != 0) {
  171. cleanup_output();
  172. return ret;
  173. }
  174. /* Server won't quit unless TLS test has worked. */
  175. #ifdef HAVE_STACK_SIZE
  176. fputs("reaping echoserver_test: ", stdout);
  177. StackSizeCheck_reap(serverThread, serverThreadStackContext);
  178. #else
  179. join_thread(serverThread);
  180. #endif
  181. if (server_args.return_code != 0) {
  182. cleanup_output();
  183. return server_args.return_code;
  184. }
  185. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
  186. defined(HAVE_CRL) && defined(HAVE_CRL_MONITOR)
  187. ret = test_crl_monitor();
  188. if (ret != 0) {
  189. cleanup_output();
  190. return ret;
  191. }
  192. #endif
  193. #endif /* !NETOS */
  194. show_ciphers();
  195. #if !defined(NETOS)
  196. ret = validate_cleanup_output();
  197. if (ret != 0)
  198. return EXIT_FAILURE;
  199. #endif
  200. wolfSSL_Cleanup();
  201. FreeTcpReady(&ready);
  202. #ifdef WOLFSSL_TIRTOS
  203. fdCloseSession(Task_self());
  204. #endif
  205. #ifdef HAVE_WNR
  206. if (wc_FreeNetRandom() < 0)
  207. err_sys("Failed to free netRandom context");
  208. #endif /* HAVE_WNR */
  209. printf("\nAll tests passed!\n");
  210. #else
  211. (void)argc;
  212. (void)argv;
  213. #endif /* !NO_WOLFSSL_SERVER && !NO_WOLFSSL_CLIENT */
  214. return EXIT_SUCCESS;
  215. }
  216. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
  217. defined(HAVE_CRL) && defined(HAVE_CRL_MONITOR)
  218. #define CRL_MONITOR_TEST_ROUNDS 6
  219. #define CRL_MONITOR_REM_FILE_ATTEMPTS 20
  220. static int test_crl_monitor(void)
  221. {
  222. func_args server_args;
  223. func_args client_args;
  224. THREAD_TYPE serverThread;
  225. tcp_ready ready;
  226. char buf[128];
  227. char tmpDir[16];
  228. char rounds[4];
  229. const char* serverArgv[] = {
  230. "testsuite",
  231. "-A", "certs/ca-cert.pem",
  232. "--crl-dir", tmpDir,
  233. "-C", rounds,
  234. "--quieter",
  235. "-x"
  236. };
  237. const char* clientArgv[] = {
  238. "testsuite",
  239. "-C",
  240. "-c", "certs/server-cert.pem",
  241. "-k", "certs/server-key.pem",
  242. "--quieter",
  243. "-H", "exitWithRet"
  244. };
  245. int ret = -1;
  246. int i = -1, j;
  247. printf("\nRunning CRL monitor test\n");
  248. sprintf(rounds, "%d", CRL_MONITOR_TEST_ROUNDS);
  249. XMEMSET(&server_args, 0, sizeof(func_args));
  250. XMEMSET(&client_args, 0, sizeof(func_args));
  251. /* Create temp dir */
  252. if (create_tmp_dir(tmpDir, sizeof(tmpDir) - 1) == NULL) {
  253. fprintf(stderr, "Failed to create tmp dir");
  254. goto cleanup;
  255. }
  256. server_args.argv = (char**)serverArgv;
  257. server_args.argc = sizeof(serverArgv) / sizeof(*serverArgv);
  258. client_args.signal = server_args.signal = &ready;
  259. client_args.argv = (char**)clientArgv;
  260. client_args.argc = sizeof(clientArgv) / sizeof(*clientArgv);
  261. InitTcpReady(&ready);
  262. start_thread(server_test, &server_args, &serverThread);
  263. wait_tcp_ready(&server_args);
  264. for (i = 0; i < CRL_MONITOR_TEST_ROUNDS; i++) {
  265. int expectFail;
  266. if (i % 2 == 0) {
  267. /* succeed on even rounds */
  268. sprintf(buf, "%s/%s", tmpDir, "crl.pem");
  269. if (copy_file("certs/crl/crl.pem", buf) != 0) {
  270. fprintf(stderr, "[%d] Failed to copy file to %s\n", i, buf);
  271. goto cleanup;
  272. }
  273. sprintf(buf, "%s/%s", tmpDir, "crl.revoked");
  274. /* The monitor can be holding the file handle and this will cause
  275. * the remove call to fail. Let's give the monitor a some time to
  276. * finish up. */
  277. for (j = 0; j < CRL_MONITOR_REM_FILE_ATTEMPTS; j++) {
  278. /* i == 0 since there is nothing to delete in the first round */
  279. if (i == 0 || rem_file(buf) == 0)
  280. break;
  281. XSLEEP_MS(100);
  282. }
  283. if (j == CRL_MONITOR_REM_FILE_ATTEMPTS) {
  284. fprintf(stderr, "[%d] Failed to remove file %s\n", i, buf);
  285. goto cleanup;
  286. }
  287. expectFail = 0;
  288. }
  289. else {
  290. /* fail on odd rounds */
  291. sprintf(buf, "%s/%s", tmpDir, "crl.revoked");
  292. if (copy_file("certs/crl/crl.revoked", buf) != 0) {
  293. fprintf(stderr, "[%d] Failed to copy file to %s\n", i, buf);
  294. goto cleanup;
  295. }
  296. sprintf(buf, "%s/%s", tmpDir, "crl.pem");
  297. /* The monitor can be holding the file handle and this will cause
  298. * the remove call to fail. Let's give the monitor a some time to
  299. * finish up. */
  300. for (j = 0; j < CRL_MONITOR_REM_FILE_ATTEMPTS; j++) {
  301. if (rem_file(buf) == 0)
  302. break;
  303. XSLEEP_MS(100);
  304. }
  305. if (j == CRL_MONITOR_REM_FILE_ATTEMPTS) {
  306. fprintf(stderr, "[%d] Failed to remove file %s\n", i, buf);
  307. goto cleanup;
  308. }
  309. expectFail = 1;
  310. }
  311. /* Give server a moment to register the file change */
  312. XSLEEP_MS(100);
  313. client_args.return_code = 0;
  314. client_test(&client_args);
  315. if (!expectFail) {
  316. if (client_args.return_code != 0) {
  317. fprintf(stderr, "[%d] Incorrect return %d\n", i,
  318. client_args.return_code);
  319. goto cleanup;
  320. }
  321. }
  322. else {
  323. if (client_args.return_code == 0) {
  324. fprintf(stderr, "[%d] Expected failure\n", i);
  325. goto cleanup;
  326. }
  327. }
  328. }
  329. join_thread(serverThread);
  330. ret = 0;
  331. cleanup:
  332. if (ret != 0 && i >= 0)
  333. fprintf(stderr, "test_crl_monitor failed on iteration %d\n", i);
  334. sprintf(buf, "%s/%s", tmpDir, "crl.pem");
  335. rem_file(buf);
  336. sprintf(buf, "%s/%s", tmpDir, "crl.revoked");
  337. rem_file(buf);
  338. (void)rem_dir(tmpDir);
  339. return ret;
  340. }
  341. #endif
  342. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
  343. (!defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLF_CRYPTO_CB_ONLY_ECC))
  344. /* Perform a basic TLS handshake.
  345. *
  346. * First connection to echo a file.
  347. * Second to tell TLS server to quit.
  348. *
  349. * @param [in,out] server_args Object sent to server thread.
  350. * @return 0 on success.
  351. * @return echoclient error return code on failure.
  352. */
  353. static int test_tls(func_args* server_args)
  354. {
  355. func_args echo_args;
  356. char* myArgv[NUMARGS];
  357. char arg[3][128];
  358. printf("\nRunning TLS test\n");
  359. /* Set up command line arguments for echoclient to send input file
  360. * and write echoed data to temporary output file. */
  361. myArgv[0] = arg[0];
  362. myArgv[1] = arg[1];
  363. myArgv[2] = arg[2];
  364. echo_args.argc = 3;
  365. echo_args.argv = myArgv;
  366. XSTRLCPY(arg[0], "testsuite", sizeof(arg[0]));
  367. XSTRLCPY(arg[1], "input", sizeof(arg[1]));
  368. XSTRLCPY(arg[2], outputName, sizeof(arg[2]));
  369. /* Share the signal, it has the new port number in it. */
  370. echo_args.signal = server_args->signal;
  371. /* Ready to execute client - wait for server to be ready. */
  372. wait_tcp_ready(server_args);
  373. /* Do a client TLS connection. */
  374. #ifdef HAVE_STACK_SIZE
  375. fputs("echoclient_test #1: ", stdout);
  376. StackSizeCheck(&echo_args, echoclient_test_wrapper);
  377. #else
  378. echoclient_test(&echo_args);
  379. #endif
  380. if (echo_args.return_code != 0)
  381. return echo_args.return_code;
  382. #ifdef WOLFSSL_DTLS
  383. /* Ensure server is ready for UDP data. */
  384. wait_tcp_ready(server_args);
  385. #endif
  386. /* Next client connection - send quit to shutdown server. */
  387. echo_args.argc = 2;
  388. XSTRLCPY(arg[1], "quit", sizeof(arg[1]));
  389. /* Do a client TLS connection. */
  390. #ifdef HAVE_STACK_SIZE
  391. fputs("echoclient_test #2: ", stdout);
  392. StackSizeCheck(&echo_args, echoclient_test_wrapper);
  393. #else
  394. echoclient_test(&echo_args);
  395. #endif
  396. if (echo_args.return_code != 0)
  397. return echo_args.return_code;
  398. return 0;
  399. }
  400. /* Show cipher suites available. */
  401. static void show_ciphers(void)
  402. {
  403. char ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
  404. XMEMSET(ciphers, 0, sizeof(ciphers));
  405. wolfSSL_get_ciphers(ciphers, sizeof(ciphers)-1);
  406. printf("ciphers = %s\n", ciphers);
  407. }
  408. /* Cleanup temporary output file. */
  409. static void cleanup_output(void)
  410. {
  411. remove(outputName);
  412. }
  413. /* Validate output equals input using a hash. Remove temporary output file.
  414. *
  415. * @return 0 on success.
  416. * @return 1 on failure.
  417. */
  418. static int validate_cleanup_output(void)
  419. {
  420. #ifndef NO_SHA256
  421. byte input[WC_SHA256_DIGEST_SIZE];
  422. byte output[WC_SHA256_DIGEST_SIZE];
  423. file_test("input", input);
  424. file_test(outputName, output);
  425. #endif
  426. cleanup_output();
  427. #ifndef NO_SHA256
  428. if (memcmp(input, output, sizeof(input)) != 0)
  429. return 1;
  430. #endif
  431. return 0;
  432. }
  433. /* Simple server.
  434. *
  435. * @param [in] args Object for server data in thread.
  436. * @return Return code.
  437. */
  438. #ifdef HAVE_STACK_SIZE
  439. static THREAD_RETURN simple_test(func_args* args)
  440. #else
  441. static void simple_test(func_args* args)
  442. #endif
  443. {
  444. THREAD_TYPE serverThread;
  445. int i;
  446. func_args svrArgs;
  447. char *svrArgv[9];
  448. char argvs[9][32];
  449. func_args cliArgs;
  450. char *cliArgv[NUMARGS];
  451. char argvc[3][32];
  452. printf("\nRunning simple test\n");
  453. for (i = 0; i < 9; i++)
  454. svrArgv[i] = argvs[i];
  455. for (i = 0; i < 3; i++)
  456. cliArgv[i] = argvc[i];
  457. XSTRLCPY(argvs[0], "SimpleServer", sizeof(argvs[0]));
  458. svrArgs.argc = 1;
  459. svrArgs.argv = svrArgv;
  460. svrArgs.return_code = 0;
  461. #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_SNIFFER) && \
  462. !defined(WOLFSSL_TIRTOS)
  463. XSTRLCPY(argvs[svrArgs.argc++], "-p", sizeof(argvs[svrArgs.argc]));
  464. XSTRLCPY(argvs[svrArgs.argc++], "0", sizeof(argvs[svrArgs.argc]));
  465. #endif
  466. /* Set the last arg later, when it is known. */
  467. args->return_code = 0;
  468. svrArgs.signal = args->signal;
  469. start_thread(server_test, &svrArgs, &serverThread);
  470. wait_tcp_ready(&svrArgs);
  471. /* Setting the actual port number. */
  472. XSTRLCPY(argvc[0], "SimpleClient", sizeof(argvc[0]));
  473. cliArgs.argv = cliArgv;
  474. cliArgs.return_code = 0;
  475. #ifndef USE_WINDOWS_API
  476. cliArgs.argc = NUMARGS;
  477. XSTRLCPY(argvc[1], "-p", sizeof(argvc[1]));
  478. (void)snprintf(argvc[2], sizeof(argvc[2]), "%d", (int)svrArgs.signal->port);
  479. #else
  480. cliArgs.argc = 1;
  481. #endif
  482. client_test(&cliArgs);
  483. if (cliArgs.return_code != 0) {
  484. args->return_code = cliArgs.return_code;
  485. #ifdef HAVE_STACK_SIZE
  486. return (THREAD_RETURN)0;
  487. #else
  488. return;
  489. #endif
  490. }
  491. join_thread(serverThread);
  492. if (svrArgs.return_code != 0) args->return_code = svrArgs.return_code;
  493. #ifdef HAVE_STACK_SIZE
  494. return (THREAD_RETURN)0;
  495. #endif
  496. }
  497. #endif /* !NO_WOLFSSL_SERVER && !NO_WOLFSSL_CLIENT */
  498. /* Wait for the server to be ready for a connection.
  499. *
  500. * @param [in] args Object to send to thread.
  501. */
  502. void wait_tcp_ready(func_args* args)
  503. {
  504. #if defined(HAVE_PTHREAD)
  505. PTHREAD_CHECK_RET(pthread_mutex_lock(&args->signal->mutex));
  506. if (!args->signal->ready)
  507. PTHREAD_CHECK_RET(pthread_cond_wait(&args->signal->cond,
  508. &args->signal->mutex));
  509. args->signal->ready = 0; /* reset */
  510. PTHREAD_CHECK_RET(pthread_mutex_unlock(&args->signal->mutex));
  511. #elif defined(NETOS)
  512. (void)tx_mutex_get(&args->signal->mutex, TX_WAIT_FOREVER);
  513. /* TODO:
  514. * if (!args->signal->ready)
  515. * pthread_cond_wait(&args->signal->cond, &args->signal->mutex);
  516. * args->signal->ready = 0; */
  517. (void)tx_mutex_put(&args->signal->mutex);
  518. #elif defined(USE_WINDOWS_API)
  519. /* Give peer a moment to get running */
  520. #if defined(__MINGW32__) || defined(__MINGW64__)
  521. Sleep(500);
  522. #else
  523. _sleep(500);
  524. #endif
  525. (void)args;
  526. #else
  527. (void)args;
  528. #endif /* thread checks */
  529. }
  530. /* Start a thread.
  531. *
  532. * @param [in] fun Function to execute in thread.
  533. * @param [in] args Object to send to function in thread.
  534. * @param [out] thread Handle to thread.
  535. */
  536. void start_thread(THREAD_CB fun, func_args* args, THREAD_TYPE* thread)
  537. {
  538. #if defined(HAVE_PTHREAD)
  539. PTHREAD_CHECK_RET(pthread_create(thread, 0, fun, args));
  540. return;
  541. #elif defined(WOLFSSL_TIRTOS)
  542. /* Initialize the defaults and set the parameters. */
  543. Task_Params taskParams;
  544. Task_Params_init(&taskParams);
  545. taskParams.arg0 = (UArg)args;
  546. taskParams.stackSize = 65535;
  547. *thread = Task_create((Task_FuncPtr)fun, &taskParams, NULL);
  548. if (*thread == NULL) {
  549. printf("Failed to create new Task\n");
  550. }
  551. Task_yield();
  552. #elif defined(NETOS)
  553. /* This can be adjusted by defining in user_settings.h, will default to 65k
  554. * in the event it is undefined */
  555. #ifndef TESTSUITE_THREAD_STACK_SZ
  556. #define TESTSUITE_THREAD_STACK_SZ 65535
  557. #endif
  558. int result;
  559. static void * TestSuiteThreadStack = NULL;
  560. /* Assume only one additional thread is created concurrently. */
  561. if (TestSuiteThreadStack == NULL)
  562. {
  563. TestSuiteThreadStack = (void *)malloc(TESTSUITE_THREAD_STACK_SZ);
  564. if (TestSuiteThreadStack == NULL)
  565. {
  566. printf ("Stack allocation failure.\n");
  567. return;
  568. }
  569. }
  570. memset (thread, 0, sizeof *thread);
  571. /* first create the idle thread:
  572. * ARGS:
  573. * Param1: pointer to thread
  574. * Param2: name
  575. * Param3 and 4: entry function and input
  576. * Param5: pointer to thread stack
  577. * Param6: stack size
  578. * Param7 and 8: priority level and preempt threshold
  579. * Param9 and 10: time slice and auto-start indicator */
  580. result = tx_thread_create(thread,
  581. "WolfSSL TestSuiteThread",
  582. (entry_functionType)fun, (ULONG)args,
  583. TestSuiteThreadStack,
  584. TESTSUITE_THREAD_STACK_SZ,
  585. 2, 2,
  586. 1, TX_AUTO_START);
  587. if (result != TX_SUCCESS)
  588. {
  589. printf("Ethernet Bypass Application: failed to create idle thread!\n");
  590. }
  591. /* end if NETOS */
  592. #else
  593. /* windows thread type */
  594. *thread = (THREAD_TYPE)_beginthreadex(NULL, 0, fun, args, 0, 0);
  595. #endif /* thread types */
  596. }
  597. /* Join thread to wait for completion.
  598. *
  599. * @param [in] thread Handle to thread.
  600. */
  601. void join_thread(THREAD_TYPE thread)
  602. {
  603. #if defined(HAVE_PTHREAD)
  604. PTHREAD_CHECK_RET(pthread_join(thread, 0));
  605. #elif defined(WOLFSSL_TIRTOS)
  606. while(1) {
  607. if (Task_getMode(thread) == Task_Mode_TERMINATED) {
  608. Task_sleep(5);
  609. break;
  610. }
  611. Task_yield();
  612. }
  613. #elif defined(NETOS)
  614. /* TODO: */
  615. #else
  616. DWORD res = WaitForSingleObject((HANDLE)thread, INFINITE);
  617. assert(res == WAIT_OBJECT_0);
  618. res = CloseHandle((HANDLE)thread);
  619. assert(res);
  620. (void)res; /* Suppress un-used variable warning */
  621. #endif
  622. }
  623. #ifndef NO_SHA256
  624. /* Create SHA-256 hash of the file based on filename.
  625. *
  626. * @param [in] file Name of file.
  627. * @parma [out] check Buffer to hold SHA-256 hash.
  628. */
  629. void file_test(const char* file, byte* check)
  630. {
  631. FILE* f;
  632. int i = 0, j, ret;
  633. wc_Sha256 sha256;
  634. byte buf[1024];
  635. byte shasum[WC_SHA256_DIGEST_SIZE];
  636. ret = wc_InitSha256(&sha256);
  637. if (ret != 0) {
  638. printf("Can't wc_InitSha256 %d\n", ret);
  639. return;
  640. }
  641. if( !( f = fopen( file, "rb" ) )) {
  642. printf("Can't open %s\n", file);
  643. return;
  644. }
  645. while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 ) {
  646. ret = wc_Sha256Update(&sha256, buf, i);
  647. if (ret != 0) {
  648. printf("Can't wc_Sha256Update %d\n", ret);
  649. fclose(f);
  650. return;
  651. }
  652. }
  653. ret = wc_Sha256Final(&sha256, shasum);
  654. wc_Sha256Free(&sha256);
  655. if (ret != 0) {
  656. printf("Can't wc_Sha256Final %d\n", ret);
  657. fclose(f);
  658. return;
  659. }
  660. XMEMCPY(check, shasum, sizeof(shasum));
  661. for(j = 0; j < WC_SHA256_DIGEST_SIZE; ++j )
  662. printf( "%02x", shasum[j] );
  663. printf(" %s\n", file);
  664. fclose(f);
  665. }
  666. #endif
  667. #else /* SINGLE_THREADED */
  668. int myoptind = 0;
  669. char* myoptarg = NULL;
  670. int main(int argc, char** argv)
  671. {
  672. func_args wolfcrypt_test_args;
  673. wolfcrypt_test_args.argc = argc;
  674. wolfcrypt_test_args.argv = argv;
  675. wolfSSL_Init();
  676. ChangeToWolfRoot();
  677. /* No TLS - only doing cryptographic algorithm testing. */
  678. wolfcrypt_test(&wolfcrypt_test_args);
  679. if (wolfcrypt_test_args.return_code != 0)
  680. return wolfcrypt_test_args.return_code;
  681. wolfSSL_Cleanup();
  682. printf("\nAll tests passed!\n");
  683. return EXIT_SUCCESS;
  684. }
  685. #endif /* SINGLE_THREADED */