/*
 * Copyright 2019-2021 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
 */

#include <openssl/crypto.h>
#include <openssl/core_dispatch.h>
#include "crypto/cryptlib.h"
#include "prov/providercommon.h"
#include "internal/thread_once.h"

#ifdef FIPS_MODULE
#include "prov/provider_ctx.h"

/*
 * Thread aware code may want to be told about thread stop events. We register
 * to hear about those thread stop events when we see a new thread has started.
 * We call the ossl_init_thread_start function to do that. In the FIPS provider
 * we have our own copy of ossl_init_thread_start, which cascades notifications
 * about threads stopping from libcrypto to all the code in the FIPS provider
 * that needs to know about it.
 *
 * The FIPS provider tells libcrypto about which threads it is interested in
 * by calling "c_thread_start" which is a function pointer created during
 * provider initialisation (i.e. OSSL_init_provider).
 */
extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
#endif

typedef struct thread_event_handler_st THREAD_EVENT_HANDLER;
struct thread_event_handler_st {
#ifndef FIPS_MODULE
    const void *index;
#endif
    void *arg;
    OSSL_thread_stop_handler_fn handfn;
    THREAD_EVENT_HANDLER *next;
};

#ifndef FIPS_MODULE
DEFINE_SPECIAL_STACK_OF(THREAD_EVENT_HANDLER_PTR, THREAD_EVENT_HANDLER *)

typedef struct global_tevent_register_st GLOBAL_TEVENT_REGISTER;
struct global_tevent_register_st {
    STACK_OF(THREAD_EVENT_HANDLER_PTR) *skhands;
    CRYPTO_RWLOCK *lock;
};

static GLOBAL_TEVENT_REGISTER *glob_tevent_reg = NULL;

static CRYPTO_ONCE tevent_register_runonce = CRYPTO_ONCE_STATIC_INIT;

DEFINE_RUN_ONCE_STATIC(create_global_tevent_register)
{
    glob_tevent_reg = OPENSSL_zalloc(sizeof(*glob_tevent_reg));
    if (glob_tevent_reg == NULL)
        return 0;

    glob_tevent_reg->skhands = sk_THREAD_EVENT_HANDLER_PTR_new_null();
    glob_tevent_reg->lock = CRYPTO_THREAD_lock_new();
    if (glob_tevent_reg->skhands == NULL || glob_tevent_reg->lock == NULL) {
        sk_THREAD_EVENT_HANDLER_PTR_free(glob_tevent_reg->skhands);
        CRYPTO_THREAD_lock_free(glob_tevent_reg->lock);
        OPENSSL_free(glob_tevent_reg);
        glob_tevent_reg = NULL;
        return 0;
    }

    return 1;
}

static GLOBAL_TEVENT_REGISTER *get_global_tevent_register(void)
{
    if (!RUN_ONCE(&tevent_register_runonce, create_global_tevent_register))
        return NULL;
    return glob_tevent_reg;
}
#endif

#ifndef FIPS_MODULE
static int  init_thread_push_handlers(THREAD_EVENT_HANDLER **hands);
static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin);
static void init_thread_destructor(void *hands);
static int  init_thread_deregister(void *arg, int all);
#endif
static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands);

static THREAD_EVENT_HANDLER **
init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep)
{
    THREAD_EVENT_HANDLER **hands = CRYPTO_THREAD_get_local(local);

    if (alloc) {
        if (hands == NULL) {

            if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL)
                return NULL;

            if (!CRYPTO_THREAD_set_local(local, hands)) {
                OPENSSL_free(hands);
                return NULL;
            }

#ifndef FIPS_MODULE
            if (!init_thread_push_handlers(hands)) {
                CRYPTO_THREAD_set_local(local, NULL);
                OPENSSL_free(hands);
                return NULL;
            }
#endif
        }
    } else if (!keep) {
        CRYPTO_THREAD_set_local(local, NULL);
    }

    return hands;
}

#ifndef FIPS_MODULE
/*
 * Since per-thread-specific-data destructors are not universally
 * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key
 * is assumed to have destructor associated. And then an effort is made
 * to call this single destructor on non-pthread platform[s].
 *
 * Initial value is "impossible". It is used as guard value to shortcut
 * destructor for threads terminating before libcrypto is initialized or
 * after it's de-initialized. Access to the key doesn't have to be
 * serialized for the said threads, because they didn't use libcrypto
 * and it doesn't matter if they pick "impossible" or dereference real
 * key value and pull NULL past initialization in the first thread that
 * intends to use libcrypto.
 */
static union {
    long sane;
    CRYPTO_THREAD_LOCAL value;
} destructor_key = { -1 };

/*
 * The thread event handler list is a thread specific linked list
 * of callback functions which are invoked in list order by the
 * current thread in case of certain events. (Currently, there is
 * only one type of event, the 'thread stop' event.)
 *
 * We also keep a global reference to that linked list, so that we
 * can deregister handlers if necessary before all the threads are
 * stopped.
 */
static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands)
{
    int ret;
    GLOBAL_TEVENT_REGISTER *gtr;

    gtr = get_global_tevent_register();
    if (gtr == NULL)
        return 0;

    if (!CRYPTO_THREAD_write_lock(gtr->lock))
        return 0;
    ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0);
    CRYPTO_THREAD_unlock(gtr->lock);

    return ret;
}

static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin)
{
    GLOBAL_TEVENT_REGISTER *gtr;
    int i;

    gtr = get_global_tevent_register();
    if (gtr == NULL)
        return;
    if (!CRYPTO_THREAD_write_lock(gtr->lock))
        return;
    for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
        THREAD_EVENT_HANDLER **hands
            = sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);

        if (hands == handsin) {
            sk_THREAD_EVENT_HANDLER_PTR_delete(gtr->skhands, i);
            CRYPTO_THREAD_unlock(gtr->lock);
            return;
        }
    }
    CRYPTO_THREAD_unlock(gtr->lock);
    return;
}

static void init_thread_destructor(void *hands)
{
    init_thread_stop(NULL, (THREAD_EVENT_HANDLER **)hands);
    init_thread_remove_handlers(hands);
    OPENSSL_free(hands);
}

int ossl_init_thread(void)
{
    if (!CRYPTO_THREAD_init_local(&destructor_key.value,
                                  init_thread_destructor))
        return 0;

    return 1;
}

void ossl_cleanup_thread(void)
{
    init_thread_deregister(NULL, 1);
    CRYPTO_THREAD_cleanup_local(&destructor_key.value);
    destructor_key.sane = -1;
}

void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx)
{
    ctx = ossl_lib_ctx_get_concrete(ctx);
    /*
     * It would be nice if we could figure out a way to do this on all threads
     * that have used the OSSL_LIB_CTX when the context is freed. This is
     * currently not possible due to the use of thread local variables.
     */
    ossl_ctx_thread_stop(ctx);
}

void OPENSSL_thread_stop(void)
{
    if (destructor_key.sane != -1) {
        THREAD_EVENT_HANDLER **hands
            = init_get_thread_local(&destructor_key.value, 0, 0);
        init_thread_stop(NULL, hands);

        init_thread_remove_handlers(hands);
        OPENSSL_free(hands);
    }
}

void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
{
    if (destructor_key.sane != -1) {
        THREAD_EVENT_HANDLER **hands
            = init_get_thread_local(&destructor_key.value, 0, 1);
        init_thread_stop(ctx, hands);
    }
}

#else

static void *thread_event_ossl_ctx_new(OSSL_LIB_CTX *libctx)
{
    THREAD_EVENT_HANDLER **hands = NULL;
    CRYPTO_THREAD_LOCAL *tlocal = OPENSSL_zalloc(sizeof(*tlocal));

    if (tlocal == NULL)
        return NULL;

    if (!CRYPTO_THREAD_init_local(tlocal,  NULL)) {
        goto err;
    }

    hands = OPENSSL_zalloc(sizeof(*hands));
    if (hands == NULL)
        goto err;

    if (!CRYPTO_THREAD_set_local(tlocal, hands))
        goto err;

    return tlocal;
 err:
    OPENSSL_free(hands);
    OPENSSL_free(tlocal);
    return NULL;
}

static void thread_event_ossl_ctx_free(void *tlocal)
{
    OPENSSL_free(tlocal);
}

static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = {
    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
    thread_event_ossl_ctx_new,
    thread_event_ossl_ctx_free,
};

static void ossl_arg_thread_stop(void *arg)
{
    ossl_ctx_thread_stop((OSSL_LIB_CTX *)arg);
}

void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
{
    THREAD_EVENT_HANDLER **hands;
    CRYPTO_THREAD_LOCAL *local
        = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX,
                                &thread_event_ossl_ctx_method);

    if (local == NULL)
        return;
    hands = init_get_thread_local(local, 0, 0);
    init_thread_stop(ctx, hands);
    OPENSSL_free(hands);
}
#endif /* FIPS_MODULE */


static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands)
{
    THREAD_EVENT_HANDLER *curr, *prev = NULL, *tmp;
#ifndef FIPS_MODULE
    GLOBAL_TEVENT_REGISTER *gtr;
#endif

    /* Can't do much about this */
    if (hands == NULL)
        return;

#ifndef FIPS_MODULE
    gtr = get_global_tevent_register();
    if (gtr == NULL)
        return;

    if (!CRYPTO_THREAD_write_lock(gtr->lock))
        return;
#endif

    curr = *hands;
    while (curr != NULL) {
        if (arg != NULL && curr->arg != arg) {
            prev = curr;
            curr = curr->next;
            continue;
        }
        curr->handfn(curr->arg);
        if (prev == NULL)
            *hands = curr->next;
        else
            prev->next = curr->next;

        tmp = curr;
        curr = curr->next;

        OPENSSL_free(tmp);
    }
#ifndef FIPS_MODULE
    CRYPTO_THREAD_unlock(gtr->lock);
#endif
}

int ossl_init_thread_start(const void *index, void *arg,
                           OSSL_thread_stop_handler_fn handfn)
{
    THREAD_EVENT_HANDLER **hands;
    THREAD_EVENT_HANDLER *hand;
#ifdef FIPS_MODULE
    OSSL_LIB_CTX *ctx = arg;

    /*
     * In FIPS mode the list of THREAD_EVENT_HANDLERs is unique per combination
     * of OSSL_LIB_CTX and thread. This is because in FIPS mode each
     * OSSL_LIB_CTX gets informed about thread stop events individually.
     */
    CRYPTO_THREAD_LOCAL *local
        = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX,
                                &thread_event_ossl_ctx_method);
#else
    /*
     * Outside of FIPS mode the list of THREAD_EVENT_HANDLERs is unique per
     * thread, but may hold multiple OSSL_LIB_CTXs. We only get told about
     * thread stop events globally, so we have to ensure all affected
     * OSSL_LIB_CTXs are informed.
     */
    CRYPTO_THREAD_LOCAL *local = &destructor_key.value;
#endif

    hands = init_get_thread_local(local, 1, 0);
    if (hands == NULL)
        return 0;

#ifdef FIPS_MODULE
    if (*hands == NULL) {
        /*
         * We've not yet registered any handlers for this thread. We need to get
         * libcrypto to tell us about later thread stop events. c_thread_start
         * is a callback to libcrypto defined in fipsprov.c
         */
        if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_arg_thread_stop,
                            ctx))
            return 0;
    }
#endif

    hand = OPENSSL_malloc(sizeof(*hand));
    if (hand == NULL)
        return 0;

    hand->handfn = handfn;
    hand->arg = arg;
#ifndef FIPS_MODULE
    hand->index = index;
#endif
    hand->next = *hands;
    *hands = hand;

    return 1;
}

#ifndef FIPS_MODULE
static int init_thread_deregister(void *index, int all)
{
    GLOBAL_TEVENT_REGISTER *gtr;
    int i;

    gtr = get_global_tevent_register();
    if (gtr == NULL)
        return 0;
    if (!all) {
        if (!CRYPTO_THREAD_write_lock(gtr->lock))
            return 0;
    } else {
        glob_tevent_reg = NULL;
    }
    for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
        THREAD_EVENT_HANDLER **hands
            = sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);
        THREAD_EVENT_HANDLER *curr = NULL, *prev = NULL, *tmp;

        if (hands == NULL) {
            if (!all)
                CRYPTO_THREAD_unlock(gtr->lock);
            return 0;
        }
        curr = *hands;
        while (curr != NULL) {
            if (all || curr->index == index) {
                if (prev != NULL)
                    prev->next = curr->next;
                else
                    *hands = curr->next;
                tmp = curr;
                curr = curr->next;
                OPENSSL_free(tmp);
                continue;
            }
            prev = curr;
            curr = curr->next;
        }
        if (all)
            OPENSSL_free(hands);
    }
    if (all) {
        CRYPTO_THREAD_lock_free(gtr->lock);
        sk_THREAD_EVENT_HANDLER_PTR_free(gtr->skhands);
        OPENSSL_free(gtr);
    } else {
        CRYPTO_THREAD_unlock(gtr->lock);
    }
    return 1;
}

int ossl_init_thread_deregister(void *index)
{
    return init_thread_deregister(index, 0);
}
#endif
