threadstest.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. /*
  2. * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /*
  10. * The test_multi_downgrade_shared_pkey function tests the thread safety of a
  11. * deprecated function.
  12. */
  13. #ifndef OPENSSL_NO_DEPRECATED_3_0
  14. # define OPENSSL_SUPPRESS_DEPRECATED
  15. #endif
  16. #if defined(_WIN32)
  17. # include <windows.h>
  18. #endif
  19. #include <string.h>
  20. #include <openssl/crypto.h>
  21. #include <openssl/rsa.h>
  22. #include <openssl/aes.h>
  23. #include <openssl/err.h>
  24. #include <openssl/rand.h>
  25. #include "internal/tsan_assist.h"
  26. #include "internal/nelem.h"
  27. #include "testutil.h"
  28. #include "threadstest.h"
  29. /* Limit the maximum number of threads */
  30. #define MAXIMUM_THREADS 10
  31. /* Limit the maximum number of providers loaded into a library context */
  32. #define MAXIMUM_PROVIDERS 4
  33. static int do_fips = 0;
  34. static char *privkey;
  35. static char *config_file = NULL;
  36. static int multidefault_run = 0;
  37. static const char *default_provider[] = { "default", NULL };
  38. static const char *fips_provider[] = { "fips", NULL };
  39. static const char *fips_and_default_providers[] = { "default", "fips", NULL };
  40. static CRYPTO_RWLOCK *global_lock;
  41. #ifdef TSAN_REQUIRES_LOCKING
  42. static CRYPTO_RWLOCK *tsan_lock;
  43. #endif
  44. /* Grab a globally unique integer value, return 0 on failure */
  45. static int get_new_uid(void)
  46. {
  47. /*
  48. * Start with a nice large number to avoid potential conflicts when
  49. * we generate a new OID.
  50. */
  51. static TSAN_QUALIFIER int current_uid = 1 << (sizeof(int) * 8 - 2);
  52. #ifdef TSAN_REQUIRES_LOCKING
  53. int r;
  54. if (!TEST_true(CRYPTO_THREAD_write_lock(tsan_lock)))
  55. return 0;
  56. r = ++current_uid;
  57. if (!TEST_true(CRYPTO_THREAD_unlock(tsan_lock)))
  58. return 0;
  59. return r;
  60. #else
  61. return tsan_counter(&current_uid);
  62. #endif
  63. }
  64. static int test_lock(void)
  65. {
  66. CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
  67. int res;
  68. res = TEST_true(CRYPTO_THREAD_read_lock(lock))
  69. && TEST_true(CRYPTO_THREAD_unlock(lock))
  70. && TEST_true(CRYPTO_THREAD_write_lock(lock))
  71. && TEST_true(CRYPTO_THREAD_unlock(lock));
  72. CRYPTO_THREAD_lock_free(lock);
  73. return res;
  74. }
  75. static CRYPTO_ONCE once_run = CRYPTO_ONCE_STATIC_INIT;
  76. static unsigned once_run_count = 0;
  77. static void once_do_run(void)
  78. {
  79. once_run_count++;
  80. }
  81. static void once_run_thread_cb(void)
  82. {
  83. CRYPTO_THREAD_run_once(&once_run, once_do_run);
  84. }
  85. static int test_once(void)
  86. {
  87. thread_t thread;
  88. if (!TEST_true(run_thread(&thread, once_run_thread_cb))
  89. || !TEST_true(wait_for_thread(thread))
  90. || !CRYPTO_THREAD_run_once(&once_run, once_do_run)
  91. || !TEST_int_eq(once_run_count, 1))
  92. return 0;
  93. return 1;
  94. }
  95. static CRYPTO_THREAD_LOCAL thread_local_key;
  96. static unsigned destructor_run_count = 0;
  97. static int thread_local_thread_cb_ok = 0;
  98. static void thread_local_destructor(void *arg)
  99. {
  100. unsigned *count;
  101. if (arg == NULL)
  102. return;
  103. count = arg;
  104. (*count)++;
  105. }
  106. static void thread_local_thread_cb(void)
  107. {
  108. void *ptr;
  109. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  110. if (!TEST_ptr_null(ptr)
  111. || !TEST_true(CRYPTO_THREAD_set_local(&thread_local_key,
  112. &destructor_run_count)))
  113. return;
  114. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  115. if (!TEST_ptr_eq(ptr, &destructor_run_count))
  116. return;
  117. thread_local_thread_cb_ok = 1;
  118. }
  119. static int test_thread_local(void)
  120. {
  121. thread_t thread;
  122. void *ptr = NULL;
  123. if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
  124. thread_local_destructor)))
  125. return 0;
  126. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  127. if (!TEST_ptr_null(ptr)
  128. || !TEST_true(run_thread(&thread, thread_local_thread_cb))
  129. || !TEST_true(wait_for_thread(thread))
  130. || !TEST_int_eq(thread_local_thread_cb_ok, 1))
  131. return 0;
  132. #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
  133. ptr = CRYPTO_THREAD_get_local(&thread_local_key);
  134. if (!TEST_ptr_null(ptr))
  135. return 0;
  136. # if !defined(OPENSSL_SYS_WINDOWS)
  137. if (!TEST_int_eq(destructor_run_count, 1))
  138. return 0;
  139. # endif
  140. #endif
  141. if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
  142. return 0;
  143. return 1;
  144. }
  145. static int test_atomic(void)
  146. {
  147. int val = 0, ret = 0, testresult = 0;
  148. uint64_t val64 = 1, ret64 = 0;
  149. CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
  150. if (!TEST_ptr(lock))
  151. return 0;
  152. if (CRYPTO_atomic_add(&val, 1, &ret, NULL)) {
  153. /* This succeeds therefore we're on a platform with lockless atomics */
  154. if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
  155. goto err;
  156. } else {
  157. /* This failed therefore we're on a platform without lockless atomics */
  158. if (!TEST_int_eq(val, 0) || !TEST_int_eq(val, ret))
  159. goto err;
  160. }
  161. val = 0;
  162. ret = 0;
  163. if (!TEST_true(CRYPTO_atomic_add(&val, 1, &ret, lock)))
  164. goto err;
  165. if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
  166. goto err;
  167. if (CRYPTO_atomic_or(&val64, 2, &ret64, NULL)) {
  168. /* This succeeds therefore we're on a platform with lockless atomics */
  169. if (!TEST_uint_eq((unsigned int)val64, 3)
  170. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  171. goto err;
  172. } else {
  173. /* This failed therefore we're on a platform without lockless atomics */
  174. if (!TEST_uint_eq((unsigned int)val64, 1)
  175. || !TEST_int_eq((unsigned int)ret64, 0))
  176. goto err;
  177. }
  178. val64 = 1;
  179. ret64 = 0;
  180. if (!TEST_true(CRYPTO_atomic_or(&val64, 2, &ret64, lock)))
  181. goto err;
  182. if (!TEST_uint_eq((unsigned int)val64, 3)
  183. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  184. goto err;
  185. ret64 = 0;
  186. if (CRYPTO_atomic_load(&val64, &ret64, NULL)) {
  187. /* This succeeds therefore we're on a platform with lockless atomics */
  188. if (!TEST_uint_eq((unsigned int)val64, 3)
  189. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  190. goto err;
  191. } else {
  192. /* This failed therefore we're on a platform without lockless atomics */
  193. if (!TEST_uint_eq((unsigned int)val64, 3)
  194. || !TEST_int_eq((unsigned int)ret64, 0))
  195. goto err;
  196. }
  197. ret64 = 0;
  198. if (!TEST_true(CRYPTO_atomic_load(&val64, &ret64, lock)))
  199. goto err;
  200. if (!TEST_uint_eq((unsigned int)val64, 3)
  201. || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
  202. goto err;
  203. testresult = 1;
  204. err:
  205. CRYPTO_THREAD_lock_free(lock);
  206. return testresult;
  207. }
  208. static OSSL_LIB_CTX *multi_libctx = NULL;
  209. static int multi_success;
  210. static OSSL_PROVIDER *multi_provider[MAXIMUM_PROVIDERS + 1];
  211. static size_t multi_num_threads;
  212. static thread_t multi_threads[MAXIMUM_THREADS];
  213. static void multi_intialise(void)
  214. {
  215. multi_success = 1;
  216. multi_libctx = NULL;
  217. multi_num_threads = 0;
  218. memset(multi_threads, 0, sizeof(multi_threads));
  219. memset(multi_provider, 0, sizeof(multi_provider));
  220. }
  221. static void multi_set_success(int ok)
  222. {
  223. if (CRYPTO_THREAD_write_lock(global_lock) == 0) {
  224. /* not synchronized, but better than not reporting failure */
  225. multi_success = ok;
  226. return;
  227. }
  228. multi_success = ok;
  229. CRYPTO_THREAD_unlock(global_lock);
  230. }
  231. static void thead_teardown_libctx(void)
  232. {
  233. OSSL_PROVIDER **p;
  234. for (p = multi_provider; *p != NULL; p++)
  235. OSSL_PROVIDER_unload(*p);
  236. OSSL_LIB_CTX_free(multi_libctx);
  237. multi_intialise();
  238. }
  239. static int thread_setup_libctx(int libctx, const char *providers[])
  240. {
  241. size_t n;
  242. if (libctx && !TEST_true(test_get_libctx(&multi_libctx, NULL, config_file,
  243. NULL, NULL)))
  244. return 0;
  245. if (providers != NULL)
  246. for (n = 0; providers[n] != NULL; n++)
  247. if (!TEST_size_t_lt(n, MAXIMUM_PROVIDERS)
  248. || !TEST_ptr(multi_provider[n] = OSSL_PROVIDER_load(multi_libctx,
  249. providers[n]))) {
  250. thead_teardown_libctx();
  251. return 0;
  252. }
  253. return 1;
  254. }
  255. static int teardown_threads(void)
  256. {
  257. size_t i;
  258. for (i = 0; i < multi_num_threads; i++)
  259. if (!TEST_true(wait_for_thread(multi_threads[i])))
  260. return 0;
  261. return 1;
  262. }
  263. static int start_threads(size_t n, void (*thread_func)(void))
  264. {
  265. size_t i;
  266. if (!TEST_size_t_le(multi_num_threads + n, MAXIMUM_THREADS))
  267. return 0;
  268. for (i = 0 ; i < n; i++)
  269. if (!TEST_true(run_thread(multi_threads + multi_num_threads++, thread_func)))
  270. return 0;
  271. return 1;
  272. }
  273. /* Template multi-threaded test function */
  274. static int thread_run_test(void (*main_func)(void),
  275. size_t num_threads, void (*thread_func)(void),
  276. int libctx, const char *providers[])
  277. {
  278. int testresult = 0;
  279. multi_intialise();
  280. if (!thread_setup_libctx(libctx, providers)
  281. || !start_threads(num_threads, thread_func))
  282. goto err;
  283. if (main_func != NULL)
  284. main_func();
  285. if (!teardown_threads()
  286. || !TEST_true(multi_success))
  287. goto err;
  288. testresult = 1;
  289. err:
  290. thead_teardown_libctx();
  291. return testresult;
  292. }
  293. static void thread_general_worker(void)
  294. {
  295. EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
  296. EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
  297. EVP_CIPHER_CTX *cipherctx = EVP_CIPHER_CTX_new();
  298. EVP_CIPHER *ciph = EVP_CIPHER_fetch(multi_libctx, "AES-128-CBC", NULL);
  299. const char *message = "Hello World";
  300. size_t messlen = strlen(message);
  301. /* Should be big enough for encryption output too */
  302. unsigned char out[EVP_MAX_MD_SIZE];
  303. const unsigned char key[AES_BLOCK_SIZE] = {
  304. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  305. 0x0c, 0x0d, 0x0e, 0x0f
  306. };
  307. const unsigned char iv[AES_BLOCK_SIZE] = {
  308. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  309. 0x0c, 0x0d, 0x0e, 0x0f
  310. };
  311. unsigned int mdoutl;
  312. int ciphoutl;
  313. EVP_PKEY *pkey = NULL;
  314. int testresult = 0;
  315. int i, isfips;
  316. isfips = OSSL_PROVIDER_available(multi_libctx, "fips");
  317. if (!TEST_ptr(mdctx)
  318. || !TEST_ptr(md)
  319. || !TEST_ptr(cipherctx)
  320. || !TEST_ptr(ciph))
  321. goto err;
  322. /* Do some work */
  323. for (i = 0; i < 5; i++) {
  324. if (!TEST_true(EVP_DigestInit_ex(mdctx, md, NULL))
  325. || !TEST_true(EVP_DigestUpdate(mdctx, message, messlen))
  326. || !TEST_true(EVP_DigestFinal(mdctx, out, &mdoutl)))
  327. goto err;
  328. }
  329. for (i = 0; i < 5; i++) {
  330. if (!TEST_true(EVP_EncryptInit_ex(cipherctx, ciph, NULL, key, iv))
  331. || !TEST_true(EVP_EncryptUpdate(cipherctx, out, &ciphoutl,
  332. (unsigned char *)message,
  333. messlen))
  334. || !TEST_true(EVP_EncryptFinal(cipherctx, out, &ciphoutl)))
  335. goto err;
  336. }
  337. /*
  338. * We want the test to run quickly - not securely.
  339. * Therefore we use an insecure bit length where we can (512).
  340. * In the FIPS module though we must use a longer length.
  341. */
  342. pkey = EVP_PKEY_Q_keygen(multi_libctx, NULL, "RSA", isfips ? 2048 : 512);
  343. if (!TEST_ptr(pkey))
  344. goto err;
  345. testresult = 1;
  346. err:
  347. EVP_MD_CTX_free(mdctx);
  348. EVP_MD_free(md);
  349. EVP_CIPHER_CTX_free(cipherctx);
  350. EVP_CIPHER_free(ciph);
  351. EVP_PKEY_free(pkey);
  352. if (!testresult)
  353. multi_set_success(0);
  354. }
  355. static void thread_multi_simple_fetch(void)
  356. {
  357. EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
  358. if (md != NULL)
  359. EVP_MD_free(md);
  360. else
  361. multi_set_success(0);
  362. }
  363. static EVP_PKEY *shared_evp_pkey = NULL;
  364. static void thread_shared_evp_pkey(void)
  365. {
  366. char *msg = "Hello World";
  367. unsigned char ctbuf[256];
  368. unsigned char ptbuf[256];
  369. size_t ptlen, ctlen = sizeof(ctbuf);
  370. EVP_PKEY_CTX *ctx = NULL;
  371. int success = 0;
  372. int i;
  373. for (i = 0; i < 1 + do_fips; i++) {
  374. if (i > 0)
  375. EVP_PKEY_CTX_free(ctx);
  376. ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey,
  377. i == 0 ? "provider=default"
  378. : "provider=fips");
  379. if (!TEST_ptr(ctx))
  380. goto err;
  381. if (!TEST_int_ge(EVP_PKEY_encrypt_init(ctx), 0)
  382. || !TEST_int_ge(EVP_PKEY_encrypt(ctx, ctbuf, &ctlen,
  383. (unsigned char *)msg, strlen(msg)),
  384. 0))
  385. goto err;
  386. EVP_PKEY_CTX_free(ctx);
  387. ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey, NULL);
  388. if (!TEST_ptr(ctx))
  389. goto err;
  390. ptlen = sizeof(ptbuf);
  391. if (!TEST_int_ge(EVP_PKEY_decrypt_init(ctx), 0)
  392. || !TEST_int_gt(EVP_PKEY_decrypt(ctx, ptbuf, &ptlen, ctbuf, ctlen),
  393. 0)
  394. || !TEST_mem_eq(msg, strlen(msg), ptbuf, ptlen))
  395. goto err;
  396. }
  397. success = 1;
  398. err:
  399. EVP_PKEY_CTX_free(ctx);
  400. if (!success)
  401. multi_set_success(0);
  402. }
  403. static void thread_provider_load_unload(void)
  404. {
  405. OSSL_PROVIDER *deflt = OSSL_PROVIDER_load(multi_libctx, "default");
  406. if (!TEST_ptr(deflt)
  407. || !TEST_true(OSSL_PROVIDER_available(multi_libctx, "default")))
  408. multi_set_success(0);
  409. OSSL_PROVIDER_unload(deflt);
  410. }
  411. static int test_multi_general_worker_default_provider(void)
  412. {
  413. return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
  414. 1, default_provider);
  415. }
  416. static int test_multi_general_worker_fips_provider(void)
  417. {
  418. if (!do_fips)
  419. return TEST_skip("FIPS not supported");
  420. return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
  421. 1, fips_provider);
  422. }
  423. static int test_multi_fetch_worker(void)
  424. {
  425. return thread_run_test(&thread_multi_simple_fetch,
  426. 2, &thread_multi_simple_fetch, 1, default_provider);
  427. }
  428. static int test_multi_shared_pkey_common(void (*worker)(void))
  429. {
  430. int testresult = 0;
  431. multi_intialise();
  432. if (!thread_setup_libctx(1, do_fips ? fips_and_default_providers
  433. : default_provider)
  434. || !TEST_ptr(shared_evp_pkey = load_pkey_pem(privkey, multi_libctx))
  435. || !start_threads(1, &thread_shared_evp_pkey)
  436. || !start_threads(1, worker))
  437. goto err;
  438. thread_shared_evp_pkey();
  439. if (!teardown_threads()
  440. || !TEST_true(multi_success))
  441. goto err;
  442. testresult = 1;
  443. err:
  444. EVP_PKEY_free(shared_evp_pkey);
  445. thead_teardown_libctx();
  446. return testresult;
  447. }
  448. #ifndef OPENSSL_NO_DEPRECATED_3_0
  449. static void thread_downgrade_shared_evp_pkey(void)
  450. {
  451. /*
  452. * This test is only relevant for deprecated functions that perform
  453. * downgrading
  454. */
  455. if (EVP_PKEY_get0_RSA(shared_evp_pkey) == NULL)
  456. multi_set_success(0);
  457. }
  458. static int test_multi_downgrade_shared_pkey(void)
  459. {
  460. return test_multi_shared_pkey_common(&thread_downgrade_shared_evp_pkey);
  461. }
  462. #endif
  463. static int test_multi_shared_pkey(void)
  464. {
  465. return test_multi_shared_pkey_common(&thread_shared_evp_pkey);
  466. }
  467. static int test_multi_load_unload_provider(void)
  468. {
  469. EVP_MD *sha256 = NULL;
  470. OSSL_PROVIDER *prov = NULL;
  471. int testresult = 0;
  472. multi_intialise();
  473. if (!thread_setup_libctx(1, NULL)
  474. || !TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, "default"))
  475. || !TEST_ptr(sha256 = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL))
  476. || !TEST_true(OSSL_PROVIDER_unload(prov)))
  477. goto err;
  478. prov = NULL;
  479. if (!start_threads(2, &thread_provider_load_unload))
  480. goto err;
  481. thread_provider_load_unload();
  482. if (!teardown_threads()
  483. || !TEST_true(multi_success))
  484. goto err;
  485. testresult = 1;
  486. err:
  487. OSSL_PROVIDER_unload(prov);
  488. EVP_MD_free(sha256);
  489. thead_teardown_libctx();
  490. return testresult;
  491. }
  492. static char *multi_load_provider = "legacy";
  493. /*
  494. * This test attempts to load several providers at the same time, and if
  495. * run with a thread sanitizer, should crash if the core provider code
  496. * doesn't synchronize well enough.
  497. */
  498. static void test_multi_load_worker(void)
  499. {
  500. OSSL_PROVIDER *prov;
  501. if (!TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, multi_load_provider))
  502. || !TEST_true(OSSL_PROVIDER_unload(prov)))
  503. multi_set_success(0);
  504. }
  505. static int test_multi_default(void)
  506. {
  507. /* Avoid running this test twice */
  508. if (multidefault_run) {
  509. TEST_skip("multi default test already run");
  510. return 1;
  511. }
  512. multidefault_run = 1;
  513. return thread_run_test(&thread_multi_simple_fetch,
  514. 2, &thread_multi_simple_fetch, 0, default_provider);
  515. }
  516. static int test_multi_load(void)
  517. {
  518. int res = 1;
  519. OSSL_PROVIDER *prov;
  520. /* The multidefault test must run prior to this test */
  521. if (!multidefault_run) {
  522. TEST_info("Running multi default test first");
  523. res = test_multi_default();
  524. }
  525. /*
  526. * We use the legacy provider in test_multi_load_worker because it uses a
  527. * child libctx that might hit more codepaths that might be sensitive to
  528. * threading issues. But in a no-legacy build that won't be loadable so
  529. * we use the default provider instead.
  530. */
  531. prov = OSSL_PROVIDER_load(NULL, "legacy");
  532. if (prov == NULL) {
  533. TEST_info("Cannot load legacy provider - assuming this is a no-legacy build");
  534. multi_load_provider = "default";
  535. }
  536. OSSL_PROVIDER_unload(prov);
  537. return thread_run_test(NULL, MAXIMUM_THREADS, &test_multi_load_worker, 0,
  538. NULL) && res;
  539. }
  540. static void test_obj_create_one(void)
  541. {
  542. char tids[12], oid[40], sn[30], ln[30];
  543. int id = get_new_uid();
  544. BIO_snprintf(tids, sizeof(tids), "%d", id);
  545. BIO_snprintf(oid, sizeof(oid), "1.3.6.1.4.1.16604.%s", tids);
  546. BIO_snprintf(sn, sizeof(sn), "short-name-%s", tids);
  547. BIO_snprintf(ln, sizeof(ln), "long-name-%s", tids);
  548. if (!TEST_int_ne(id, 0)
  549. || !TEST_true(id = OBJ_create(oid, sn, ln))
  550. || !TEST_true(OBJ_add_sigid(id, NID_sha3_256, NID_rsa)))
  551. multi_set_success(0);
  552. }
  553. static int test_obj_add(void)
  554. {
  555. return thread_run_test(&test_obj_create_one,
  556. MAXIMUM_THREADS, &test_obj_create_one,
  557. 1, default_provider);
  558. }
  559. static void test_lib_ctx_load_config_worker(void)
  560. {
  561. if (!TEST_int_eq(OSSL_LIB_CTX_load_config(multi_libctx, config_file), 1))
  562. multi_set_success(0);
  563. }
  564. static int test_lib_ctx_load_config(void)
  565. {
  566. return thread_run_test(&test_lib_ctx_load_config_worker,
  567. MAXIMUM_THREADS, &test_lib_ctx_load_config_worker,
  568. 1, default_provider);
  569. }
  570. #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
  571. static BIO *multi_bio1, *multi_bio2;
  572. static void test_bio_dgram_pair_worker(void)
  573. {
  574. ossl_unused int r;
  575. int ok = 0;
  576. uint8_t ch = 0;
  577. uint8_t scratch[64];
  578. BIO_MSG msg = {0};
  579. size_t num_processed = 0;
  580. if (!TEST_int_eq(RAND_bytes_ex(multi_libctx, &ch, 1, 64), 1))
  581. goto err;
  582. msg.data = scratch;
  583. msg.data_len = sizeof(scratch);
  584. /*
  585. * We do not test for failure here as recvmmsg may fail if no sendmmsg
  586. * has been called yet. The purpose of this code is to exercise tsan.
  587. */
  588. if (ch & 2)
  589. r = BIO_sendmmsg(ch & 1 ? multi_bio2 : multi_bio1, &msg,
  590. sizeof(BIO_MSG), 1, 0, &num_processed);
  591. else
  592. r = BIO_recvmmsg(ch & 1 ? multi_bio2 : multi_bio1, &msg,
  593. sizeof(BIO_MSG), 1, 0, &num_processed);
  594. ok = 1;
  595. err:
  596. if (ok == 0)
  597. multi_set_success(0);
  598. }
  599. static int test_bio_dgram_pair(void)
  600. {
  601. int r;
  602. BIO *bio1 = NULL, *bio2 = NULL;
  603. r = BIO_new_bio_dgram_pair(&bio1, 0, &bio2, 0);
  604. if (!TEST_int_eq(r, 1))
  605. goto err;
  606. multi_bio1 = bio1;
  607. multi_bio2 = bio2;
  608. r = thread_run_test(&test_bio_dgram_pair_worker,
  609. MAXIMUM_THREADS, &test_bio_dgram_pair_worker,
  610. 1, default_provider);
  611. err:
  612. BIO_free(bio1);
  613. BIO_free(bio2);
  614. return r;
  615. }
  616. #endif
  617. typedef enum OPTION_choice {
  618. OPT_ERR = -1,
  619. OPT_EOF = 0,
  620. OPT_FIPS, OPT_CONFIG_FILE,
  621. OPT_TEST_ENUM
  622. } OPTION_CHOICE;
  623. const OPTIONS *test_get_options(void)
  624. {
  625. static const OPTIONS options[] = {
  626. OPT_TEST_OPTIONS_DEFAULT_USAGE,
  627. { "fips", OPT_FIPS, '-', "Test the FIPS provider" },
  628. { "config", OPT_CONFIG_FILE, '<',
  629. "The configuration file to use for the libctx" },
  630. { NULL }
  631. };
  632. return options;
  633. }
  634. int setup_tests(void)
  635. {
  636. OPTION_CHOICE o;
  637. char *datadir;
  638. while ((o = opt_next()) != OPT_EOF) {
  639. switch (o) {
  640. case OPT_FIPS:
  641. do_fips = 1;
  642. break;
  643. case OPT_CONFIG_FILE:
  644. config_file = opt_arg();
  645. break;
  646. case OPT_TEST_CASES:
  647. break;
  648. default:
  649. return 0;
  650. }
  651. }
  652. if (!TEST_ptr(datadir = test_get_argument(0)))
  653. return 0;
  654. privkey = test_mk_file_path(datadir, "rsakey.pem");
  655. if (!TEST_ptr(privkey))
  656. return 0;
  657. if (!TEST_ptr(global_lock = CRYPTO_THREAD_lock_new()))
  658. return 0;
  659. #ifdef TSAN_REQUIRES_LOCKING
  660. if (!TEST_ptr(tsan_lock = CRYPTO_THREAD_lock_new()))
  661. return 0;
  662. #endif
  663. /* Keep first to validate auto creation of default library context */
  664. ADD_TEST(test_multi_default);
  665. ADD_TEST(test_lock);
  666. ADD_TEST(test_once);
  667. ADD_TEST(test_thread_local);
  668. ADD_TEST(test_atomic);
  669. ADD_TEST(test_multi_load);
  670. ADD_TEST(test_multi_general_worker_default_provider);
  671. ADD_TEST(test_multi_general_worker_fips_provider);
  672. ADD_TEST(test_multi_fetch_worker);
  673. ADD_TEST(test_multi_shared_pkey);
  674. #ifndef OPENSSL_NO_DEPRECATED_3_0
  675. ADD_TEST(test_multi_downgrade_shared_pkey);
  676. #endif
  677. ADD_TEST(test_multi_load_unload_provider);
  678. ADD_TEST(test_obj_add);
  679. ADD_TEST(test_lib_ctx_load_config);
  680. #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
  681. ADD_TEST(test_bio_dgram_pair);
  682. #endif
  683. return 1;
  684. }
  685. void cleanup_tests(void)
  686. {
  687. OPENSSL_free(privkey);
  688. #ifdef TSAN_REQUIRES_LOCKING
  689. CRYPTO_THREAD_lock_free(tsan_lock);
  690. #endif
  691. CRYPTO_THREAD_lock_free(global_lock);
  692. }