/*
 * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/*
 * The test_multi_downgrade_shared_pkey function tests the thread safety of a
 * deprecated function.
 */
#ifndef OPENSSL_NO_DEPRECATED_3_0
# define OPENSSL_SUPPRESS_DEPRECATED
#endif

#if defined(_WIN32)
# include <windows.h>
#endif

#include <string.h>
#include <openssl/crypto.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>
#include <openssl/err.h>
#include "internal/tsan_assist.h"
#include "internal/nelem.h"
#include "testutil.h"
#include "threadstest.h"

/* Limit the maximum number of threads */
#define MAXIMUM_THREADS     10

/* Limit the maximum number of providers loaded into a library context */
#define MAXIMUM_PROVIDERS   4

static int do_fips = 0;
static char *privkey;
static char *config_file = NULL;
static int multidefault_run = 0;

static const char *default_provider[] = { "default", NULL };
static const char *fips_provider[] = { "fips", NULL };
static const char *fips_and_default_providers[] = { "default", "fips", NULL };

#ifdef TSAN_REQUIRES_LOCKING
static CRYPTO_RWLOCK *tsan_lock;
#endif

/* Grab a globally unique integer value, return 0 on failure */
static int get_new_uid(void)
{
    /*
     * Start with a nice large number to avoid potential conflicts when
     * we generate a new OID.
     */
    static TSAN_QUALIFIER int current_uid = 1 << (sizeof(int) * 8 - 2);
#ifdef TSAN_REQUIRES_LOCKING
    int r;

    if (!TEST_true(CRYPTO_THREAD_write_lock(tsan_lock)))
        return 0;
    r = ++current_uid;
    if (!TEST_true(CRYPTO_THREAD_unlock(tsan_lock)))
        return 0;
    return r;

#else
    return tsan_counter(&current_uid);
#endif
}

static int test_lock(void)
{
    CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();
    int res;

    res = TEST_true(CRYPTO_THREAD_read_lock(lock))
          && TEST_true(CRYPTO_THREAD_unlock(lock))
          && TEST_true(CRYPTO_THREAD_write_lock(lock))
          && TEST_true(CRYPTO_THREAD_unlock(lock));

    CRYPTO_THREAD_lock_free(lock);

    return res;
}

static CRYPTO_ONCE once_run = CRYPTO_ONCE_STATIC_INIT;
static unsigned once_run_count = 0;

static void once_do_run(void)
{
    once_run_count++;
}

static void once_run_thread_cb(void)
{
    CRYPTO_THREAD_run_once(&once_run, once_do_run);
}

static int test_once(void)
{
    thread_t thread;

    if (!TEST_true(run_thread(&thread, once_run_thread_cb))
        || !TEST_true(wait_for_thread(thread))
        || !CRYPTO_THREAD_run_once(&once_run, once_do_run)
        || !TEST_int_eq(once_run_count, 1))
        return 0;
    return 1;
}

static CRYPTO_THREAD_LOCAL thread_local_key;
static unsigned destructor_run_count = 0;
static int thread_local_thread_cb_ok = 0;

static void thread_local_destructor(void *arg)
{
    unsigned *count;

    if (arg == NULL)
        return;

    count = arg;

    (*count)++;
}

static void thread_local_thread_cb(void)
{
    void *ptr;

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (!TEST_ptr_null(ptr)
        || !TEST_true(CRYPTO_THREAD_set_local(&thread_local_key,
                                              &destructor_run_count)))
        return;

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (!TEST_ptr_eq(ptr, &destructor_run_count))
        return;

    thread_local_thread_cb_ok = 1;
}

static int test_thread_local(void)
{
    thread_t thread;
    void *ptr = NULL;

    if (!TEST_true(CRYPTO_THREAD_init_local(&thread_local_key,
                                            thread_local_destructor)))
        return 0;

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (!TEST_ptr_null(ptr)
        || !TEST_true(run_thread(&thread, thread_local_thread_cb))
        || !TEST_true(wait_for_thread(thread))
        || !TEST_int_eq(thread_local_thread_cb_ok, 1))
        return 0;

#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)

    ptr = CRYPTO_THREAD_get_local(&thread_local_key);
    if (!TEST_ptr_null(ptr))
        return 0;

# if !defined(OPENSSL_SYS_WINDOWS)
    if (!TEST_int_eq(destructor_run_count, 1))
        return 0;
# endif
#endif

    if (!TEST_true(CRYPTO_THREAD_cleanup_local(&thread_local_key)))
        return 0;
    return 1;
}

static int test_atomic(void)
{
    int val = 0, ret = 0, testresult = 0;
    uint64_t val64 = 1, ret64 = 0;
    CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new();

    if (!TEST_ptr(lock))
        return 0;

    if (CRYPTO_atomic_add(&val, 1, &ret, NULL)) {
        /* This succeeds therefore we're on a platform with lockless atomics */
        if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
            goto err;
    } else {
        /* This failed therefore we're on a platform without lockless atomics */
        if (!TEST_int_eq(val, 0) || !TEST_int_eq(val, ret))
            goto err;
    }
    val = 0;
    ret = 0;

    if (!TEST_true(CRYPTO_atomic_add(&val, 1, &ret, lock)))
        goto err;
    if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret))
        goto err;

    if (CRYPTO_atomic_or(&val64, 2, &ret64, NULL)) {
        /* This succeeds therefore we're on a platform with lockless atomics */
        if (!TEST_uint_eq((unsigned int)val64, 3)
                || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
            goto err;
    } else {
        /* This failed therefore we're on a platform without lockless atomics */
        if (!TEST_uint_eq((unsigned int)val64, 1)
                || !TEST_int_eq((unsigned int)ret64, 0))
            goto err;
    }
    val64 = 1;
    ret64 = 0;

    if (!TEST_true(CRYPTO_atomic_or(&val64, 2, &ret64, lock)))
        goto err;

    if (!TEST_uint_eq((unsigned int)val64, 3)
            || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
        goto err;

    ret64 = 0;
    if (CRYPTO_atomic_load(&val64, &ret64, NULL)) {
        /* This succeeds therefore we're on a platform with lockless atomics */
        if (!TEST_uint_eq((unsigned int)val64, 3)
                || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
            goto err;
    } else {
        /* This failed therefore we're on a platform without lockless atomics */
        if (!TEST_uint_eq((unsigned int)val64, 3)
                || !TEST_int_eq((unsigned int)ret64, 0))
            goto err;
    }

    ret64 = 0;
    if (!TEST_true(CRYPTO_atomic_load(&val64, &ret64, lock)))
        goto err;

    if (!TEST_uint_eq((unsigned int)val64, 3)
            || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64))
        goto err;

    testresult = 1;
 err:
    CRYPTO_THREAD_lock_free(lock);
    return testresult;
}

static OSSL_LIB_CTX *multi_libctx = NULL;
static int multi_success;
static OSSL_PROVIDER *multi_provider[MAXIMUM_PROVIDERS + 1];
static size_t multi_num_threads;
static thread_t multi_threads[MAXIMUM_THREADS];

static void multi_intialise(void)
{
    multi_success = 1;
    multi_libctx = NULL;
    multi_num_threads = 0;
    memset(multi_threads, 0, sizeof(multi_threads));
    memset(multi_provider, 0, sizeof(multi_provider));
}

static void thead_teardown_libctx(void)
{
    OSSL_PROVIDER **p;

    for (p = multi_provider; *p != NULL; p++)
        OSSL_PROVIDER_unload(*p);
    OSSL_LIB_CTX_free(multi_libctx);
    multi_intialise();
}

static int thread_setup_libctx(int libctx, const char *providers[])
{
    size_t n;

    if (libctx && !TEST_true(test_get_libctx(&multi_libctx, NULL, config_file,
                                             NULL, NULL)))
        return 0;

    if (providers != NULL)
        for (n = 0; providers[n] != NULL; n++)
            if (!TEST_size_t_lt(n, MAXIMUM_PROVIDERS)
                || !TEST_ptr(multi_provider[n] = OSSL_PROVIDER_load(multi_libctx,
                                                                    providers[n]))) {
                thead_teardown_libctx();
                return 0;
            }
    return 1;
}

static int teardown_threads(void)
{
    size_t i;

    for (i = 0; i < multi_num_threads; i++)
        if (!TEST_true(wait_for_thread(multi_threads[i])))
            return 0;
    return 1;
}

static int start_threads(size_t n, void (*thread_func)(void))
{
    size_t i;

    if (!TEST_size_t_le(multi_num_threads + n, MAXIMUM_THREADS))
        return 0;

    for (i = 0 ; i < n; i++)
        if (!TEST_true(run_thread(multi_threads + multi_num_threads++, thread_func)))
            return 0;
    return 1;
}

/* Template multi-threaded test function */
static int thread_run_test(void (*main_func)(void),
                           size_t num_threads, void (*thread_func)(void),
                           int libctx, const char *providers[])
{
    int testresult = 0;

    multi_intialise();
    if (!thread_setup_libctx(libctx, providers)
            || !start_threads(num_threads, thread_func))
        goto err;

    if (main_func != NULL)
        main_func();

    if (!teardown_threads()
            || !TEST_true(multi_success))
        goto err;
    testresult = 1;
 err:
    thead_teardown_libctx();
    return testresult;
}

static void thread_general_worker(void)
{
    EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
    EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);
    EVP_CIPHER_CTX *cipherctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER *ciph = EVP_CIPHER_fetch(multi_libctx, "AES-128-CBC", NULL);
    const char *message = "Hello World";
    size_t messlen = strlen(message);
    /* Should be big enough for encryption output too */
    unsigned char out[EVP_MAX_MD_SIZE];
    const unsigned char key[AES_BLOCK_SIZE] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
        0x0c, 0x0d, 0x0e, 0x0f
    };
    const unsigned char iv[AES_BLOCK_SIZE] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
        0x0c, 0x0d, 0x0e, 0x0f
    };
    unsigned int mdoutl;
    int ciphoutl;
    EVP_PKEY *pkey = NULL;
    int testresult = 0;
    int i, isfips;

    isfips = OSSL_PROVIDER_available(multi_libctx, "fips");

    if (!TEST_ptr(mdctx)
            || !TEST_ptr(md)
            || !TEST_ptr(cipherctx)
            || !TEST_ptr(ciph))
        goto err;

    /* Do some work */
    for (i = 0; i < 5; i++) {
        if (!TEST_true(EVP_DigestInit_ex(mdctx, md, NULL))
                || !TEST_true(EVP_DigestUpdate(mdctx, message, messlen))
                || !TEST_true(EVP_DigestFinal(mdctx, out, &mdoutl)))
            goto err;
    }
    for (i = 0; i < 5; i++) {
        if (!TEST_true(EVP_EncryptInit_ex(cipherctx, ciph, NULL, key, iv))
                || !TEST_true(EVP_EncryptUpdate(cipherctx, out, &ciphoutl,
                                                (unsigned char *)message,
                                                messlen))
                || !TEST_true(EVP_EncryptFinal(cipherctx, out, &ciphoutl)))
            goto err;
    }

    /*
     * We want the test to run quickly - not securely.
     * Therefore we use an insecure bit length where we can (512).
     * In the FIPS module though we must use a longer length.
     */
    pkey = EVP_PKEY_Q_keygen(multi_libctx, NULL, "RSA", isfips ? 2048 : 512);
    if (!TEST_ptr(pkey))
        goto err;

    testresult = 1;
 err:
    EVP_MD_CTX_free(mdctx);
    EVP_MD_free(md);
    EVP_CIPHER_CTX_free(cipherctx);
    EVP_CIPHER_free(ciph);
    EVP_PKEY_free(pkey);
    if (!testresult)
        multi_success = 0;
}

static void thread_multi_simple_fetch(void)
{
    EVP_MD *md = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL);

    if (md != NULL)
        EVP_MD_free(md);
    else
        multi_success = 0;
}

static EVP_PKEY *shared_evp_pkey = NULL;

static void thread_shared_evp_pkey(void)
{
    char *msg = "Hello World";
    unsigned char ctbuf[256];
    unsigned char ptbuf[256];
    size_t ptlen, ctlen = sizeof(ctbuf);
    EVP_PKEY_CTX *ctx = NULL;
    int success = 0;
    int i;

    for (i = 0; i < 1 + do_fips; i++) {
        if (i > 0)
            EVP_PKEY_CTX_free(ctx);
        ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey,
                                         i == 0 ? "provider=default"
                                                : "provider=fips");
        if (!TEST_ptr(ctx))
            goto err;

        if (!TEST_int_ge(EVP_PKEY_encrypt_init(ctx), 0)
                || !TEST_int_ge(EVP_PKEY_encrypt(ctx, ctbuf, &ctlen,
                                                (unsigned char *)msg, strlen(msg)),
                                                0))
            goto err;

        EVP_PKEY_CTX_free(ctx);
        ctx = EVP_PKEY_CTX_new_from_pkey(multi_libctx, shared_evp_pkey, NULL);

        if (!TEST_ptr(ctx))
            goto err;

        ptlen = sizeof(ptbuf);
        if (!TEST_int_ge(EVP_PKEY_decrypt_init(ctx), 0)
                || !TEST_int_gt(EVP_PKEY_decrypt(ctx, ptbuf, &ptlen, ctbuf, ctlen),
                                                0)
                || !TEST_mem_eq(msg, strlen(msg), ptbuf, ptlen))
            goto err;
    }

    success = 1;

 err:
    EVP_PKEY_CTX_free(ctx);
    if (!success)
        multi_success = 0;
}

static void thread_provider_load_unload(void)
{
    OSSL_PROVIDER *deflt = OSSL_PROVIDER_load(multi_libctx, "default");

    if (!TEST_ptr(deflt)
            || !TEST_true(OSSL_PROVIDER_available(multi_libctx, "default")))
        multi_success = 0;

    OSSL_PROVIDER_unload(deflt);
}

static int test_multi_general_worker_default_provider(void)
{
    return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
                           1, default_provider);
}

static int test_multi_general_worker_fips_provider(void)
{
    if (!do_fips)
        return TEST_skip("FIPS not supported");
    return thread_run_test(&thread_general_worker, 2, &thread_general_worker,
                           1, fips_provider);
}

static int test_multi_fetch_worker(void)
{
    return thread_run_test(&thread_multi_simple_fetch,
                           2, &thread_multi_simple_fetch, 1, default_provider);
}

static int test_multi_shared_pkey_common(void (*worker)(void))
{
    int testresult = 0;

    multi_intialise();
    if (!thread_setup_libctx(1, do_fips ? fips_and_default_providers
                                        : default_provider)
            || !TEST_ptr(shared_evp_pkey = load_pkey_pem(privkey, multi_libctx))
            || !start_threads(1, &thread_shared_evp_pkey)
            || !start_threads(1, worker))
        goto err;

    thread_shared_evp_pkey();

    if (!teardown_threads()
            || !TEST_true(multi_success))
        goto err;
    testresult = 1;
 err:
    EVP_PKEY_free(shared_evp_pkey);
    thead_teardown_libctx();
    return testresult;
}

#ifndef OPENSSL_NO_DEPRECATED_3_0
static void thread_downgrade_shared_evp_pkey(void)
{
    /*
     * This test is only relevant for deprecated functions that perform
     * downgrading
     */
    if (EVP_PKEY_get0_RSA(shared_evp_pkey) == NULL)
        multi_success = 0;
}

static int test_multi_downgrade_shared_pkey(void)
{
    return test_multi_shared_pkey_common(&thread_downgrade_shared_evp_pkey);
}
#endif

static int test_multi_shared_pkey(void)
{
    return test_multi_shared_pkey_common(&thread_shared_evp_pkey);
}

static int test_multi_load_unload_provider(void)
{
    EVP_MD *sha256 = NULL;
    OSSL_PROVIDER *prov = NULL;
    int testresult = 0;

    multi_intialise();
    if (!thread_setup_libctx(1, NULL)
            || !TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, "default"))
            || !TEST_ptr(sha256 = EVP_MD_fetch(multi_libctx, "SHA2-256", NULL))
            || !TEST_true(OSSL_PROVIDER_unload(prov)))
        goto err;
    prov = NULL;

    if (!start_threads(2, &thread_provider_load_unload))
        goto err;

    thread_provider_load_unload();

    if (!teardown_threads()
            || !TEST_true(multi_success))
        goto err;
    testresult = 1;
 err:
    OSSL_PROVIDER_unload(prov);
    EVP_MD_free(sha256);
    thead_teardown_libctx();
    return testresult;
}

static char *multi_load_provider = "legacy";
/*
 * This test attempts to load several providers at the same time, and if
 * run with a thread sanitizer, should crash if the core provider code
 * doesn't synchronize well enough.
 */
static void test_multi_load_worker(void)
{
    OSSL_PROVIDER *prov;

    if (!TEST_ptr(prov = OSSL_PROVIDER_load(multi_libctx, multi_load_provider))
            || !TEST_true(OSSL_PROVIDER_unload(prov)))
        multi_success = 0;
}

static int test_multi_default(void)
{
    /* Avoid running this test twice */
    if (multidefault_run) {
        TEST_skip("multi default test already run");
        return 1;
    }
    multidefault_run = 1;

    return thread_run_test(&thread_multi_simple_fetch,
                           2, &thread_multi_simple_fetch, 0, default_provider);
}

static int test_multi_load(void)
{
    int res = 1;
    OSSL_PROVIDER *prov;

    /* The multidefault test must run prior to this test */
    if (!multidefault_run) {
        TEST_info("Running multi default test first");
        res = test_multi_default();
    }

    /*
     * We use the legacy provider in test_multi_load_worker because it uses a
     * child libctx that might hit more codepaths that might be sensitive to
     * threading issues. But in a no-legacy build that won't be loadable so
     * we use the default provider instead.
     */
    prov = OSSL_PROVIDER_load(NULL, "legacy");
    if (prov == NULL) {
        TEST_info("Cannot load legacy provider - assuming this is a no-legacy build");
        multi_load_provider = "default";
    }
    OSSL_PROVIDER_unload(prov);

    return thread_run_test(NULL, MAXIMUM_THREADS, &test_multi_load_worker, 0,
                          NULL) && res;
}

static void test_obj_create_one(void)
{
    char tids[12], oid[40], sn[30], ln[30];
    int id = get_new_uid();

    BIO_snprintf(tids, sizeof(tids), "%d", id);
    BIO_snprintf(oid, sizeof(oid), "1.3.6.1.4.1.16604.%s", tids);
    BIO_snprintf(sn, sizeof(sn), "short-name-%s", tids);
    BIO_snprintf(ln, sizeof(ln), "long-name-%s", tids);
    if (!TEST_int_ne(id, 0)
            || !TEST_true(id = OBJ_create(oid, sn, ln))
            || !TEST_true(OBJ_add_sigid(id, NID_sha3_256, NID_rsa)))
        multi_success = 0;
}

static int test_obj_add(void)
{
    return thread_run_test(&test_obj_create_one,
                           MAXIMUM_THREADS, &test_obj_create_one,
                           1, default_provider);
}

typedef enum OPTION_choice {
    OPT_ERR = -1,
    OPT_EOF = 0,
    OPT_FIPS, OPT_CONFIG_FILE,
    OPT_TEST_ENUM
} OPTION_CHOICE;

const OPTIONS *test_get_options(void)
{
    static const OPTIONS options[] = {
        OPT_TEST_OPTIONS_DEFAULT_USAGE,
        { "fips", OPT_FIPS, '-', "Test the FIPS provider" },
        { "config", OPT_CONFIG_FILE, '<',
          "The configuration file to use for the libctx" },
        { NULL }
    };
    return options;
}

int setup_tests(void)
{
    OPTION_CHOICE o;
    char *datadir;

    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_FIPS:
            do_fips = 1;
            break;
        case OPT_CONFIG_FILE:
            config_file = opt_arg();
            break;
        case OPT_TEST_CASES:
            break;
        default:
            return 0;
        }
    }

    if (!TEST_ptr(datadir = test_get_argument(0)))
        return 0;

    privkey = test_mk_file_path(datadir, "rsakey.pem");
    if (!TEST_ptr(privkey))
        return 0;

#ifdef TSAN_REQUIRES_LOCKING
    if (!TEST_ptr(tsan_lock = CRYPTO_THREAD_lock_new()))
        return 0;
#endif

    /* Keep first to validate auto creation of default library context */
    ADD_TEST(test_multi_default);

    ADD_TEST(test_lock);
    ADD_TEST(test_once);
    ADD_TEST(test_thread_local);
    ADD_TEST(test_atomic);
    ADD_TEST(test_multi_load);
    ADD_TEST(test_multi_general_worker_default_provider);
    ADD_TEST(test_multi_general_worker_fips_provider);
    ADD_TEST(test_multi_fetch_worker);
    ADD_TEST(test_multi_shared_pkey);
#ifndef OPENSSL_NO_DEPRECATED_3_0
    ADD_TEST(test_multi_downgrade_shared_pkey);
#endif
    ADD_TEST(test_multi_load_unload_provider);
    ADD_TEST(test_obj_add);
    return 1;
}

void cleanup_tests(void)
{
    OPENSSL_free(privkey);
#ifdef TSAN_REQUIRES_LOCKING
    CRYPTO_THREAD_lock_free(tsan_lock);
#endif
}
