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