threadstest.c 27 KB

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