OPENSSL_INIT_CRYPTO(3ossl)
π NAME π
okay so bestie, this is the <openssl/crypto.h> page (that's the manual name, OPENSSL_INIT_CRYPTO(3ossl), and yes it's giving β¨essentialβ¨). It's all about the OpenSSL initialisation and deinitialisation functions β the whole "set me up" / "tear me down" situation.
The full roster of icons on this page:
OPENSSL_INIT_newOPENSSL_INIT_set_config_filenameOPENSSL_INIT_set_config_appnameOPENSSL_INIT_set_config_file_flagsOPENSSL_INIT_freeOPENSSL_init_cryptoOPENSSL_cleanupOPENSSL_atexitOPENSSL_thread_stop_exOPENSSL_thread_stop
β¨ SYNOPSIS β¨
the receipts, verbatim, no notes π
#include <openssl/crypto.h>
void OPENSSL_cleanup(void);
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
int OPENSSL_atexit(void (*handler)(void));
void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx);
void OPENSSL_thread_stop(void);
OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void);
int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *init,
const char* filename);
int OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *init,
unsigned long flags);
int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *init,
const char* name);
void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *init);
look at all those little setup besties π«Ά each one's about to get its whole moment, don't you worry πΈ
β¨ DESCRIPTION β¨
okay so picture this: when OpenSSL (that's libcrypto, bestie) is just doing its normal lil thing, it grabs a bunch of resources at startup, and every single one of those has to get freed when the library shuts down. and lowkey, some resources are allocated per thread (only if your app is multi-threaded, no stress otherwise), and those ones have to be freed before the thread closes. no skipping that.
but here's the glow-up: as of version 1.1.0, OpenSSL justβ¦ handles it? like it automatically allocates every resource it needs, so you don't have to do any explicit initialisation at all. it also deinitialises itself automatically. main character behaviour, honestly. π
that said, sometimes you do wanna init explicitly β for example when you need some nondefault initialisation, which is very much a vibe. that's what OPENSSL_init_crypto() is for, for libcrypto (and hey, peep OPENSSL_init_ssl(3) for the libssl equivalent π«Ά).
and this part matters, so listen up: numerous internal OpenSSL functions call OPENSSL_init_crypto(). so if you want nondefault initialisation to actually happen, your application code MUST call OPENSSL_init_crypto() prior to any other OpenSSL function calls. no cap.
the opts parameter is the one that says which aspects of libcrypto should get initialised. valid options are:
π the opts menu π
OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGSβ suppresses the automatic loading of the libcrypto error strings. this is not a default option. and once you've picked it, any laterOPENSSL_init_crypto()call withOPENSSL_INIT_LOAD_CRYPTO_STRINGSjust gets ignored. πOPENSSL_INIT_LOAD_CRYPTO_STRINGSβ automatic loading of the libcrypto error strings. with this one the library loads the libcrypto error strings all by itself. this is a default option. and once selected, laterOPENSSL_init_crypto()calls withOPENSSL_INIT_NO_LOAD_CRYPTO_STRINGSget ignored.OPENSSL_INIT_ADD_ALL_CIPHERSβ the library automatically loads and makes available all libcrypto ciphers. this is a default option. once selected, laterOPENSSL_init_crypto()calls withOPENSSL_INIT_NO_ADD_ALL_CIPHERSget ignored.OPENSSL_INIT_ADD_ALL_DIGESTSβ the library automatically loads and makes available all libcrypto digests. this is a default option. once selected, laterOPENSSL_init_crypto()calls withOPENSSL_INIT_NO_ADD_ALL_DIGESTSget ignored.OPENSSL_INIT_NO_ADD_ALL_CIPHERSβ the library suppresses automatic loading of libcrypto ciphers. this is not a default option. once selected, laterOPENSSL_init_crypto()calls withOPENSSL_INIT_ADD_ALL_CIPHERSget ignored.OPENSSL_INIT_NO_ADD_ALL_DIGESTSβ the library suppresses automatic loading of libcrypto digests. this is not a default option. once selected, laterOPENSSL_init_crypto()calls withOPENSSL_INIT_ADD_ALL_DIGESTSget ignored.OPENSSL_INIT_LOAD_CONFIGβ an OpenSSL configuration file gets automatically loaded and used, by callingOPENSSL_config(). this is a default option. note that in OpenSSL 1.1.1 this was the default for libssl but not for libcrypto (checkOPENSSL_init_ssl(3)for the deets on libssl initialisation). and in OpenSSL 1.1.0 this was a nondefault option for both libssl and libcrypto. see the description ofOPENSSL_INIT_new(), down below. β¬οΈOPENSSL_INIT_NO_LOAD_CONFIGβ suppresses loading of OpenSSL configuration files. it's the equivalent of callingOPENSSL_no_config(). this is not a default option.OPENSSL_INIT_ASYNCβ the library automatically initialises the libcrypto async sub-library (seeASYNC_start_job(3)). this is a default option.OPENSSL_INIT_ENGINE_RDRANDβ the library automatically loads and initialises the RDRAND engine (if it's available). this is not a default option, and it's deprecated in OpenSSL 3.0. β οΈOPENSSL_INIT_ENGINE_DYNAMICβ the library automatically loads and initialises the dynamic engine. not a default option, and deprecated in OpenSSL 3.0.OPENSSL_INIT_ENGINE_OPENSSLβ the library automatically loads and initialises the openssl engine. not a default option, and deprecated in OpenSSL 3.0.OPENSSL_INIT_ENGINE_CRYPTODEVβ the library automatically loads and initialises the cryptodev engine (if it's available). not a default option, and deprecated in OpenSSL 3.0.OPENSSL_INIT_ENGINE_CAPIβ the library automatically loads and initialises the CAPI engine (if it's available). not a default option, and deprecated in OpenSSL 3.0.OPENSSL_INIT_ENGINE_PADLOCKβ the library automatically loads and initialises the padlock engine (if it's available). not a default option, and deprecated in OpenSSL 3.0.OPENSSL_INIT_ENGINE_AFALGβ the library automatically loads and initialises the AFALG engine. not a default option, and deprecated in OpenSSL 3.0.OPENSSL_INIT_ENGINE_ALL_BUILTINβ the library automatically loads and initialises all the built-in engines listed above, with the exception of the openssl and afalg engines. not a default option, and deprecated in OpenSSL 3.0.OPENSSL_INIT_ATFORKβ the library registers its fork handlers. seeOPENSSL_fork_prepare(3)for the details. π΄OPENSSL_INIT_NO_ATEXITβ by default OpenSSL tries to clean itself up when the process exits, via an "atexit" handler. this option suppresses that whole behaviour, which means your application has to clean up OpenSSL explicitly usingOPENSSL_cleanup(). you're on your own, bestie. π
you can absolutely stack multiple options together in one single call to OPENSSL_init_crypto(). like, for example:
OPENSSL_init_crypto(OPENSSL_INIT_NO_ADD_ALL_CIPHERS
| OPENSSL_INIT_NO_ADD_ALL_DIGESTS, NULL);
the OPENSSL_cleanup() function deinitialises OpenSSL β both libcrypto and libssl. all resources allocated by OpenSSL get freed. typically you should not need to call this directly, since it kicks in automatically when the application exits, thanks to the standard C library atexit() function. but if your application is gonna close in a way that doesn't call those registered atexit() handlers, then yeah, the application should call OPENSSL_cleanup() directly.
and real talk: developers of libraries using OpenSSL are discouraged from calling this function, and should instead typically just rely on auto-deinitialisation. this is to dodge the error conditions where both an application and a library it depends on are using OpenSSL, and the library deinitialises it before the application is actually done with it. messy. π
once OPENSSL_cleanup() has been called, the library cannot be reinitialised. attempts to call OPENSSL_init_crypto() will fail and an ERR_R_INIT_FAIL error gets added to the error stack. and heads up: because initialisation has failed, OpenSSL error strings will not be available β only an error code. you can put that code through the openssl errstr command line application to get a human readable error (see openssl-errstr(1)).
the OPENSSL_atexit() function lets you register a function to be called during OPENSSL_cleanup(). these stop handlers get called after deinitialisation of resources local to a thread, but before other process wide resources are freed. and if multiple stop handlers get registered? no guarantees are made about the order they run in. π€·
the OPENSSL_thread_stop_ex() function deallocates resources associated with the current thread, for the given OSSL_LIB_CTX ctx. and the ctx parameter can be NULL, in which case the default OSSL_LIB_CTX is used.
typically this function gets called automatically by the library when the thread exits β as long as the OSSL_LIB_CTX hasn't been freed before the thread exits. if OSSL_LIB_CTX_free() is called, OPENSSL_thread_stop_ex will be called automatically for the current thread (but not for any other threads that may have used this OSSL_LIB_CTX).
OPENSSL_thread_stop_ex should be called on all threads that will exit after the OSSL_LIB_CTX is freed. typically that's not necessary for the default OSSL_LIB_CTX (because all resources get cleaned up on library exit) β except if thread local resources should be freed before library exit, or under the circumstances described in the NOTES section below.
OPENSSL_thread_stop() is the same as OPENSSL_thread_stop_ex(), except that the default OSSL_LIB_CTX is always used.
the OPENSSL_INIT_LOAD_CONFIG flag will load a configuration file, just like CONF_modules_load_file(3) with NULL filename and application name, plus the CONF_MFLAGS_IGNORE_MISSING_FILE, CONF_MFLAGS_IGNORE_RETURN_CODES and CONF_MFLAGS_DEFAULT_SECTION flags. and you can customise the filename, application name and flags by providing a non-null OPENSSL_INIT_SETTINGS object. β¨
that object can be allocated via OPENSSL_INIT_new(). then OPENSSL_INIT_set_config_filename() lets you specify a nondefault filename β which gets copied, so it doesn't need to refer to persistent storage. similarly, OPENSSL_INIT_set_config_appname() lets you specify a nondefault application name. and finally, OPENSSL_INIT_set_file_flags lets you specify nondefault flags.
ok important: if theCONF_MFLAGS_IGNORE_RETURN_CODESflag is not included, then any errors in the configuration file will cause an error return fromOPENSSL_init_crypto, or indirectly fromOPENSSL_init_ssl(3).
the object can be released with OPENSSL_INIT_free() when you're done with it. and if the argument to OPENSSL_INIT_free() is NULL? nothing happens. iconic. π¦
π§΅ NOTES π§΅
okay bestie this is the part where we talk about thread cleanup and honestly? it's giving β¨responsibilityβ¨
so like, resources that belong to a thread? they get deallocated automatically when that thread exits. periodt π
(in a pthreads environment, that means when pthread_exit() gets called, for example).
on Windows platforms, this happens in response to a DLL_THREAD_DETACH message being sent to the libcrypto32.dll entry point. but some windows functions may cause threads to exit WITHOUT sending this message β for example ExitProcess(). π so if your app uses such functions, then the application must free up OpenSSL resources directly via a call to OPENSSL_thread_stop() on each thread. no skipping this, fr fr.
similarly, this message will also not be sent if OpenSSL is linked statically, and therefore applications using static linking should also call OPENSSL_thread_stop() on each thread. like, it's the same energy π«Ά
additionally, if OpenSSL is loaded dynamically via LoadLibrary() and the threads are not destroyed until after FreeLibrary() is called, then each thread should call OPENSSL_thread_stop() prior to the FreeLibrary() call. order matters, bestie, don't be out here doing it backwards π
on Linux/Unix where OpenSSL has been loaded via dlopen() and the application is multi-threaded, and if dlclose() is subsequently called prior to the threads being destroyed, then OpenSSL will not be able to deallocate resources associated with those threads. π
so your options are:
- call
OPENSSL_thread_stop()on each thread prior to thedlclose()call, OR - alternatively, the original
dlopen()call should use theRTLD_NODELETEflag (where available on the platform)
pick your fighter, both are valid, just don't leave it hanging β¨
β οΈ also important: thread cleanup does not unwind an OpenSSL function interrupted by cancellation or thread exit; see openssl-threads(7). not me warning you about this again, but here we are π
π« RETURN VALUES π«
here's the vibe check on what these functions hand back:
OPENSSL_init_crypto,OPENSSL_atexit()andOPENSSL_INIT_set_config_appname()return1on success or0on error.
that's it. one or zero. binary queen π
π SEE ALSO π
go read these next, i promise they're worth it:
π HISTORY π
these icons were added in OpenSSL 1.1.0:
OPENSSL_init_crypto()OPENSSL_cleanup()OPENSSL_atexit()OPENSSL_thread_stop()OPENSSL_INIT_new()OPENSSL_INIT_set_config_appname()OPENSSL_INIT_free()
an iconic era, truly π
βοΈ COPYRIGHT βοΈ
Copyright 2016-2026 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>.
aaaand that's a wrap on OPENSSL_INIT_CRYPTO(3ossl), bestie π this lil legend lives in OpenSSL 3.5.9 and it's dated 2026-09-29 β go forth and initialize responsibly, and remember: call OPENSSL_thread_stop(). i'm not asking πβ¨
π¦ where this page comes from
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms