void drbg_delete_thread_state(void) { RAND_DRBG *drbg; drbg = CRYPTO_THREAD_get_local(&public_drbg); CRYPTO_THREAD_set_local(&public_drbg, NULL); RAND_DRBG_free(drbg); drbg = CRYPTO_THREAD_get_local(&private_drbg); CRYPTO_THREAD_set_local(&private_drbg, NULL); RAND_DRBG_free(drbg); }
static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc) { struct thread_local_inits_st *local = CRYPTO_THREAD_get_local(&threadstopkey); if (local == NULL && alloc) { local = OPENSSL_zalloc(sizeof *local); CRYPTO_THREAD_set_local(&threadstopkey, local); } if (!alloc) { CRYPTO_THREAD_set_local(&threadstopkey, NULL); } return local; }
ERR_STATE *ERR_get_state(void) { ERR_STATE *state = NULL; if (!RUN_ONCE(&err_init, err_do_init)) return NULL; state = CRYPTO_THREAD_get_local(&err_thread_local); if (state == NULL) { state = OPENSSL_zalloc(sizeof(*state)); if (state == NULL) return NULL; if (!CRYPTO_THREAD_set_local(&err_thread_local, state)) { ERR_STATE_free(state); return NULL; } /* Ignore failures from these */ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE); } return state; }
/* * err_shelve_state returns the current thread local error state * and freezes the error module until err_unshelve_state is called. */ int err_shelve_state(void **state) { int saveerrno = get_last_sys_error(); /* * Note, at present our only caller is OPENSSL_init_crypto(), indirectly * via ossl_init_load_crypto_nodelete(), by which point the requested * "base" initialization has already been performed, so the below call is a * NOOP, that re-enters OPENSSL_init_crypto() only to quickly return. * * If are no other valid callers of this function, the call below can be * removed, avoiding the re-entry into OPENSSL_init_crypto(). If there are * potential uses that are not from inside OPENSSL_init_crypto(), then this * call is needed, but some care is required to make sure that the re-entry * remains a NOOP. */ if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL)) return 0; if (!RUN_ONCE(&err_init, err_do_init)) return 0; *state = CRYPTO_THREAD_get_local(&err_thread_local); if (!CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)-1)) return 0; set_sys_error(saveerrno); return 1; }
int ASYNC_init_thread(size_t max_size, size_t init_size) { async_pool *pool; size_t curr_size = 0; if (init_size > max_size) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE); return 0; } if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) { return 0; } if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) { return 0; } pool = OPENSSL_zalloc(sizeof(*pool)); if (pool == NULL) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); return 0; } pool->jobs = sk_ASYNC_JOB_new_reserve(NULL, init_size); if (pool->jobs == NULL) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); OPENSSL_free(pool); return 0; } pool->max_size = max_size; /* Pre-create jobs as required */ while (init_size--) { ASYNC_JOB *job; job = async_job_new(); if (job == NULL || !async_fibre_makecontext(&job->fibrectx)) { /* * Not actually fatal because we already created the pool, just * skip creation of any more jobs */ async_job_free(job); break; } job->funcargs = NULL; sk_ASYNC_JOB_push(pool->jobs, job); /* Cannot fail due to reserve */ curr_size++; } pool->curr_size = curr_size; if (!CRYPTO_THREAD_set_local(&poolkey, pool)) { ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL); goto err; } return 1; err: async_free_pool_internal(pool); return 0; }
static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc) { struct thread_local_inits_st *local = CRYPTO_THREAD_get_local(&destructor_key.value); if (alloc) { if (local == NULL && (local = OPENSSL_zalloc(sizeof(*local))) != NULL && !CRYPTO_THREAD_set_local(&destructor_key.value, local)) { OPENSSL_free(local); return NULL; } } else { CRYPTO_THREAD_set_local(&destructor_key.value, NULL); } return local; }
void err_delete_thread_state(void) { ERR_STATE *state = ERR_get_state(); if (state == NULL) return; CRYPTO_THREAD_set_local(&err_thread_local, NULL); ERR_STATE_free(state); }
static void async_free_pool_internal(async_pool *pool) { if (pool == NULL) return; async_empty_pool(pool); sk_ASYNC_JOB_free(pool->jobs); OPENSSL_free(pool); CRYPTO_THREAD_set_local(&poolkey, NULL); async_local_cleanup(); async_ctx_free(); }
static int async_ctx_free(void) { async_ctx *ctx; ctx = async_get_ctx(); if (!CRYPTO_THREAD_set_local(&ctxkey, NULL)) return 0; OPENSSL_free(ctx); return 1; }
ERR_STATE *ERR_get_state(void) { ERR_STATE *state; int saveerrno = get_last_sys_error(); if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL)) return NULL; if (!RUN_ONCE(&err_init, err_do_init)) return NULL; state = CRYPTO_THREAD_get_local(&err_thread_local); if (state == (ERR_STATE*)-1) return NULL; if (state == NULL) { if (!CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)-1)) return NULL; if ((state = OPENSSL_zalloc(sizeof(*state))) == NULL) { CRYPTO_THREAD_set_local(&err_thread_local, NULL); return NULL; } if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE) || !CRYPTO_THREAD_set_local(&err_thread_local, state)) { ERR_STATE_free(state); CRYPTO_THREAD_set_local(&err_thread_local, NULL); return NULL; } /* Ignore failures from these */ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); } set_sys_error(saveerrno); return state; }
/* * Get the private DRBG. * Returns pointer to the DRBG on success, NULL on failure. */ RAND_DRBG *RAND_DRBG_get0_private(void) { RAND_DRBG *drbg; if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) return NULL; drbg = CRYPTO_THREAD_get_local(&private_drbg_thread_local_key); if (drbg == NULL) { ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND); drbg = drbg_setup(drbg_master); CRYPTO_THREAD_set_local(&private_drbg_thread_local_key, drbg); } return drbg; }
/* * Get the public DRBG. * Returns pointer to the DRBG on success, NULL on failure. */ RAND_DRBG *RAND_DRBG_get0_public(void) { RAND_DRBG *drbg; if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) return NULL; drbg = CRYPTO_THREAD_get_local(&public_drbg); if (drbg == NULL) { if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND)) return NULL; drbg = drbg_setup(master_drbg); CRYPTO_THREAD_set_local(&public_drbg, drbg); } return drbg; }
static async_ctx *async_ctx_new(void) { async_ctx *nctx = NULL; nctx = OPENSSL_malloc(sizeof(*nctx)); if (nctx == NULL) { ASYNCerr(ASYNC_F_ASYNC_CTX_NEW, ERR_R_MALLOC_FAILURE); goto err; } async_fibre_init_dispatcher(&nctx->dispatcher); nctx->currjob = NULL; nctx->blocked = 0; if (!CRYPTO_THREAD_set_local(&ctxkey, nctx)) goto err; return nctx; err: OPENSSL_free(nctx); return NULL; }
/* * err_unshelve_state restores the error state that was returned * by err_shelve_state previously. */ void err_unshelve_state(void* state) { if (state != (void*)-1) CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)state); }