<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.openssl.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wdtj</id>
	<title>OpenSSLWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.openssl.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Wdtj"/>
	<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php/Special:Contributions/Wdtj"/>
	<updated>2026-04-10T06:39:16Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.13</generator>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=Library_Initialization&amp;diff=2388</id>
		<title>Library Initialization</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=Library_Initialization&amp;diff=2388"/>
		<updated>2016-05-13T14:18:13Z</updated>

		<summary type="html">&lt;p&gt;Wdtj: /* Cleanup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page discusses OpenSSL library initialization when using the &amp;lt;tt&amp;gt;libssl&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;libcrypto&amp;lt;/tt&amp;gt; components.&lt;br /&gt;
&lt;br /&gt;
There are two ways to initialize the OpenSSL library, and they depend on the version of the library you are using. If you are using OpenSSL 1.0.2 or below, then you would use &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt;. If you are using OpenSSL 1.1.0 or above, then you would use &amp;lt;tt&amp;gt;OPENSSL_init_ssl&amp;lt;/tt&amp;gt;. A compatibility macro exists in &amp;lt;tt&amp;gt;ssl.h&amp;lt;/tt&amp;gt; that maps &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;OPENSSL_init_ssl&amp;lt;/tt&amp;gt;, so you can continue to use &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt; if desired. Also see ''[http://mta.openssl.org/pipermail/openssl-dev/2016-February/005491.html SSL_library_init]'' on the OpenSSL-dev mailing list.&lt;br /&gt;
&lt;br /&gt;
If you fail to initialize the library, then you will experience unexplained errors like &amp;lt;tt&amp;gt;SSL_CTX_new&amp;lt;/tt&amp;gt; returning &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, error messages like &amp;lt;tt&amp;gt;SSL_CTX_new:library has no ciphers&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;alert handshake failure&amp;lt;/tt&amp;gt; with no shared ciphers.&lt;br /&gt;
&lt;br /&gt;
Below is a list of some initialization calls you might encounter in code or documentation. Unfortunately, all the initialization function return a useless values (for example, always 1) or are void functions. There is no way to determine if a failure occurred.&lt;br /&gt;
&lt;br /&gt;
* SSL_library_init&lt;br /&gt;
* OpenSSL_add_ssl_algorithms&lt;br /&gt;
* OpenSSL_add_all_algorithms&lt;br /&gt;
* SSL_load_error_strings&lt;br /&gt;
* ERR_load_crypto_strings&lt;br /&gt;
&lt;br /&gt;
== libssl Initialization ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;libssl&amp;lt;/tt&amp;gt; should be initialized with calls to &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;SSL_load_error_strings&amp;lt;/tt&amp;gt;. If your program is multi-threaded, you should install the static locks. If you need (or don't need) configuration from &amp;lt;tt&amp;gt;openssl.cnf&amp;lt;/tt&amp;gt;, then you should call &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;OPENSSL_noconfig&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you are supporting both pre-1.1.0 and post-1.1.0 version of the OpenSSL library and you want to take control of &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;OPENSSL_init_ssl&amp;lt;/tt&amp;gt;, then you can perform:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#include &amp;lt;openssl/opensslv.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
#if OPENSSL_VERSION_NUMBER &amp;lt; 0x10100000L&lt;br /&gt;
SSL_library_init();&lt;br /&gt;
#else&lt;br /&gt;
OPENSSL_init_ssl(0, NULL);&lt;br /&gt;
#endif&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you call &amp;lt;tt&amp;gt;libssl&amp;lt;/tt&amp;gt;, the function will also initialize &amp;lt;tt&amp;gt;libcrypto&amp;lt;/tt&amp;gt; components. There are two corner cases discussed in later sections. The first corner case is static locks, and second is &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OpenSSL_add_ssl_algorithms&amp;lt;/tt&amp;gt; is a &amp;lt;tt&amp;gt;#define&amp;lt;/tt&amp;gt; for &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt;. You only need to call one or the other. If you want to print error strings using OpenSSL's built in functions, then call &amp;lt;tt&amp;gt;SSL_load_error_strings&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt; function loads the algorithms use by &amp;lt;tt&amp;gt;libssl&amp;lt;/tt&amp;gt;. Below is an excerpt from &amp;lt;tt&amp;gt;ssl_algs.c&amp;lt;/tt&amp;gt; (with some additional formatting for clarity).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;int SSL_library_init(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
#ifndef OPENSSL_NO_DES&lt;br /&gt;
    EVP_add_cipher(EVP_des_cbc());&lt;br /&gt;
    EVP_add_cipher(EVP_des_ede3_cbc());&lt;br /&gt;
#endif&lt;br /&gt;
#ifndef OPENSSL_NO_IDEA&lt;br /&gt;
    EVP_add_cipher(EVP_idea_cbc());&lt;br /&gt;
#endif&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
#ifndef OPENSSL_NO_COMP&lt;br /&gt;
    (void)SSL_COMP_get_compression_methods();&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
    /* initialize cipher/digest methods table */&lt;br /&gt;
    ssl_load_ciphers();&lt;br /&gt;
&lt;br /&gt;
    return(1);&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The call to &amp;lt;tt&amp;gt;ssl_load_ciphers&amp;lt;/tt&amp;gt; simply builds a table for use in the library. The following is from &amp;lt;tt&amp;gt;ssl_ciph.c&amp;lt;/tt&amp;gt; (with some additional formatting for clarity).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;void ssl_load_ciphers(void)&lt;br /&gt;
{&lt;br /&gt;
    ssl_cipher_methods[SSL_ENC_DES_IDX] = EVP_get_cipherbyname(SN_des_cbc);&lt;br /&gt;
    ssl_cipher_methods[SSL_ENC_3DES_IDX] = EVP_get_cipherbyname(SN_des_ede3_cbc);&lt;br /&gt;
    ...&lt;br /&gt;
    ssl_digest_methods[SSL_MD_MD5_IDX] = EVP_get_digestbyname(SN_md5);&lt;br /&gt;
    ssl_mac_secret_size[SSL_MD_MD5_IDX] = EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]);&lt;br /&gt;
    ...&lt;br /&gt;
    ssl_digest_methods[SSL_MD_SHA384_IDX] = EVP_get_digestbyname(SN_sha384);&lt;br /&gt;
    ssl_mac_secret_size[SSL_MD_SHA384_IDX] = EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]);&lt;br /&gt;
    ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Library Apps ===&lt;br /&gt;
&lt;br /&gt;
The following examines how the OpenSSL development team uses initialization in the OpenSSL utilities.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;s_client&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* OpenSSL_add_ssl_algorithms&lt;br /&gt;
* SSL_load_error_strings&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;s_server&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* SSL_load_error_strings();&lt;br /&gt;
* OpenSSL_add_ssl_algorithms();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;s_time&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* OpenSSL_add_ssl_algorithms();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;state_machine&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* SSL_library_init();&lt;br /&gt;
* OpenSSL_add_ssl_algorithms();&lt;br /&gt;
* SSL_load_error_strings();&lt;br /&gt;
* ERR_load_crypto_strings();&lt;br /&gt;
&lt;br /&gt;
== libcrypto Initialization ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;libcrypto&amp;lt;/tt&amp;gt; should be initialized with calls to &amp;lt;tt&amp;gt;OpenSSL_add_all_algorithms&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ERR_load_crypto_strings&amp;lt;/tt&amp;gt;. If your program is multi-threaded, you should install the static locks. If you need (or don't need) configuration from &amp;lt;tt&amp;gt;openssl.cnf&amp;lt;/tt&amp;gt;, then you should call &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;OPENSSL_noconfig&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;OPENSSL_add_all_algorithms&amp;lt;/tt&amp;gt; function is &amp;lt;tt&amp;gt;#define&amp;lt;/tt&amp;gt;'d to either &amp;lt;tt&amp;gt;OPENSSL_add_all_algorithms_conf&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;OPENSSL_add_all_algorithms_noconf&amp;lt;/tt&amp;gt; depending upon the value of &amp;lt;tt&amp;gt;OPENSSL_LOAD_CONF&amp;lt;/tt&amp;gt;. A typical installation does ''not'' define &amp;lt;tt&amp;gt;OPENSSL_LOAD_CONF&amp;lt;/tt&amp;gt;, which means &amp;lt;tt&amp;gt;OPENSSL_add_all_algorithms_noconf&amp;lt;/tt&amp;gt; is used. Below is an excerpt from &amp;lt;tt&amp;gt;c_all.c&amp;lt;/tt&amp;gt; (with some additional formatting for clarity).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;void OPENSSL_add_all_algorithms_noconf(void)&lt;br /&gt;
{&lt;br /&gt;
    /*&lt;br /&gt;
     * For the moment OPENSSL_cpuid_setup does something&lt;br /&gt;
     * only on IA-32, but we reserve the option for all&lt;br /&gt;
     * platforms...&lt;br /&gt;
     */&lt;br /&gt;
    OPENSSL_cpuid_setup();&lt;br /&gt;
    OpenSSL_add_all_ciphers();&lt;br /&gt;
    OpenSSL_add_all_digests();&lt;br /&gt;
    ...&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OpenSSL_add_all_ciphers&amp;lt;/tt&amp;gt; looks a lot like &amp;lt;tt&amp;gt;SSL_library_init&amp;lt;/tt&amp;gt; from the &amp;lt;tt&amp;gt;libssl&amp;lt;/tt&amp;gt; initialization routines (sans the call to &amp;lt;tt&amp;gt;ssl_load_ciphers&amp;lt;/tt&amp;gt;). Below is an excerpt from &amp;lt;tt&amp;gt;c_allc.c&amp;lt;/tt&amp;gt; (with some additional formatting for clarity).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;void OpenSSL_add_all_ciphers(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
#ifndef OPENSSL_NO_DES&lt;br /&gt;
    EVP_add_cipher(EVP_des_cfb());&lt;br /&gt;
    EVP_add_cipher(EVP_des_cfb1());&lt;br /&gt;
    EVP_add_cipher(EVP_des_cfb8());&lt;br /&gt;
    EVP_add_cipher(EVP_des_ede_cfb());&lt;br /&gt;
    EVP_add_cipher(EVP_des_ede3_cfb());&lt;br /&gt;
    EVP_add_cipher(EVP_des_ede3_cfb1());&lt;br /&gt;
    EVP_add_cipher(EVP_des_ede3_cfb8());&lt;br /&gt;
    ...&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#ifndef OPENSSL_NO_RC4&lt;br /&gt;
    EVP_add_cipher(EVP_rc4());&lt;br /&gt;
    EVP_add_cipher(EVP_rc4_40());&lt;br /&gt;
# ifndef OPENSSL_NO_MD5&lt;br /&gt;
    EVP_add_cipher(EVP_rc4_hmac_md5());&lt;br /&gt;
# endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
    /* Note: there is no call to ssl_load_ciphers() here */&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, [http://www.openssl.org/docs/crypto/OpenSSL_add_all_algorithms.html &amp;lt;tt&amp;gt;OpenSSL_add_all_algorithms(3)&amp;lt;/tt&amp;gt;] offers the following advice:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Calling OpenSSL_add_all_algorithms() links in all algorithms: as a result a statically linked executable can be quite large. If this is important it is possible to just add the required ciphers and digests.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want the small footprint, then call &amp;lt;tt&amp;gt;EVP_add_cipher&amp;lt;/tt&amp;gt; with the ciphers and algorithms you need (and nothing more).&lt;br /&gt;
&lt;br /&gt;
=== Library Apps ===&lt;br /&gt;
&lt;br /&gt;
The following examines how the OpenSSL development team uses initialization in the OpenSSL utilities.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;enc&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* OpenSSL_add_all_algorithms();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;dec&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* OpenSSL_add_all_algorithms();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;pkcs8&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* ERR_load_crypto_strings();&lt;br /&gt;
* OpenSSL_add_all_algorithms();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;cms_sign&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* OpenSSL_add_all_algorithms();&lt;br /&gt;
* ERR_load_crypto_strings();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;cms_ver&amp;lt;/tt&amp;gt; initializes itself with the following calls:&lt;br /&gt;
* OpenSSL_add_all_algorithms();&lt;br /&gt;
* ERR_load_crypto_strings();&lt;br /&gt;
&lt;br /&gt;
== ENGINEs and RDRAND ==&lt;br /&gt;
&lt;br /&gt;
A call to &amp;lt;tt&amp;gt;ENGINE_load_builtin_engines&amp;lt;/tt&amp;gt; loads all built-in engines, including those for &amp;lt;tt&amp;gt;AES_NI&amp;lt;/tt&amp;gt; instructions and &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt;. After the call, OpenSSL will use the engines for AES encryption and random number generation, if available. In this case, &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt; will be the only source of random numbers.&lt;br /&gt;
&lt;br /&gt;
If you are concerned over possible &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt; tampering, then you should explicitly call &amp;lt;tt&amp;gt;RAND_set_rand_engine(NULL)&amp;lt;/tt&amp;gt; after loading all engines. If another module in the program happens to call &amp;lt;tt&amp;gt;ENGINE_load_builtin_engines&amp;lt;/tt&amp;gt; again, then you will go back to using &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can also call &amp;lt;tt&amp;gt;ENGINE_unregister_RAND&amp;lt;/tt&amp;gt; followed by &amp;lt;tt&amp;gt;ENGINE_register_all_complete&amp;lt;/tt&amp;gt; to unregister &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt; as default random number generator implementation.&lt;br /&gt;
&lt;br /&gt;
To avoid accidental use of &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt;, you can build OpenSSL with &amp;lt;tt&amp;gt;OPENSSL_NO_RDRAND&amp;lt;/tt&amp;gt; defined. This is the preferred method to avoid all use of &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Future version of the library will change the default behavior. That is, in the future, you will have to explicitly call &amp;lt;tt&amp;gt;ENGINE_load_rdrand&amp;lt;/tt&amp;gt; if you want to use &amp;lt;tt&amp;gt;RDRAND&amp;lt;/tt&amp;gt;. The change has been checked in, but its only available through &amp;lt;tt&amp;gt;git&amp;lt;/tt&amp;gt; at the moment.&lt;br /&gt;
&lt;br /&gt;
For the full discussion, see coderman's ''[http://seclists.org/fulldisclosure/2013/Dec/99 RDRAND used directly when default engines loaded in openssl-1.0.1-beta1 through openssl-1.0.1e]''.&lt;br /&gt;
&lt;br /&gt;
== Static Locks ==&lt;br /&gt;
&lt;br /&gt;
If your program is multi-threaded, then you will need to install the static locks. The static locks are used for extensively for &amp;lt;tt&amp;gt;libssl&amp;lt;/tt&amp;gt;, and used in the random number generator for &amp;lt;tt&amp;gt;libcrypto&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
See [http://www.openssl.org/docs/crypto/threads.html threads(3)] for details until the wiki is updated with an example.&lt;br /&gt;
&lt;br /&gt;
== OPENSSL_config ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;OPENSSL_noconfig&amp;lt;/tt&amp;gt; loads and unloads &amp;lt;tt&amp;gt;openssl.cnf&amp;lt;/tt&amp;gt;. More correctly, a call to &amp;lt;tt&amp;gt;OPENSSL_config(NULL)&amp;lt;/tt&amp;gt; loads the default configuration in &amp;lt;tt&amp;gt;openssl.cnf&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;OPENSSL_config(filename)&amp;lt;/tt&amp;gt; loads another configuration, and &amp;lt;tt&amp;gt;OPENSSL_noconfig&amp;lt;/tt&amp;gt; unlods a configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; may (or may not) be called depending upon how the OpenSSL library was configured, and it depends on whether &amp;lt;tt&amp;gt;OPENSSL_LOAD_CONF&amp;lt;/tt&amp;gt; was defined. Because &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; may (or may not) be called, your program may or may not need to make the call to &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt;. If, for example, your program is dynamically loading an ENGINE from &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt;, then you will need to ensure a call to &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can check the value of &amp;lt;tt&amp;gt;OPENSSL_LOAD_CONF&amp;lt;/tt&amp;gt; by &amp;lt;tt&amp;gt;cat&amp;lt;/tt&amp;gt;'ing &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;openssl/opensslconf.h&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;. You can then decide to call &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;OPENSSL_noconfig&amp;lt;/tt&amp;gt; based upon the definition (or lack threof) for &amp;lt;tt&amp;gt;OPENSSL_LOAD_CONF&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ cat /usr/local/ssl/include/openssl/opensslconf.h | grep -i load&lt;br /&gt;
$&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are the rules you should observe. In either case, your program should not depend upon the OpenSSL library and get into a known state.&lt;br /&gt;
&lt;br /&gt;
* If you need something from &amp;lt;tt&amp;gt;openssl.cnf&amp;lt;/tt&amp;gt;, then call &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt;. Don't depend on the library to do it for you.&lt;br /&gt;
* If you don't need something from &amp;lt;tt&amp;gt;openssl.cnf&amp;lt;/tt&amp;gt; (or its mucking up you program), then call &amp;lt;tt&amp;gt;OPENSSL_noconfig&amp;lt;/tt&amp;gt;. The library may have called &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; for you.&lt;br /&gt;
&lt;br /&gt;
== Engines ==&lt;br /&gt;
&lt;br /&gt;
If your application needs to use engines, then it should either call call &amp;lt;tt&amp;gt;ENGINE_load_builtin_engines&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; to load the built-in engines (including dynamically configured engines from &amp;lt;tt&amp;gt;openssl.cnf&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Engines are are automatically loaded (or not loaded) based on the definition of &amp;lt;tt&amp;gt;OPENSSL_LOAD_CONF&amp;lt;/tt&amp;gt; (or lack of definition). You should not depend on library behavior, so you should call &amp;lt;tt&amp;gt;OPENSSL_config&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;ENGINE_load_builtin_engines&amp;lt;/tt&amp;gt; if you need engines.&lt;br /&gt;
&lt;br /&gt;
You can also load a particular engine if you know what you want to use. &amp;lt;tt&amp;gt;eng_all.c&amp;lt;/tt&amp;gt; lists the built-in engines you can load. For example, the following loads the &amp;lt;tt&amp;gt;rdrand&amp;lt;/tt&amp;gt; engine provided for some Intel CPUs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;unsigned long err = 0;&lt;br /&gt;
int rc = 0;&lt;br /&gt;
&lt;br /&gt;
OPENSSL_cpuid_setup();&lt;br /&gt;
ENGINE_load_rdrand();&lt;br /&gt;
&lt;br /&gt;
ENGINE* eng = ENGINE_by_id(&amp;quot;rdrand&amp;quot;);&lt;br /&gt;
if(NULL == eng) handleFailure();&lt;br /&gt;
&lt;br /&gt;
rc = ENGINE_init(eng);&lt;br /&gt;
if(1 != rc) handleFailure();&lt;br /&gt;
&lt;br /&gt;
rc = ENGINE_set_default(eng, ENGINE_METHOD_RAND);&lt;br /&gt;
if(1 != rc) handleFailure();&lt;br /&gt;
&lt;br /&gt;
/* OK to proceed */&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
ENGINE_finish(eng);&lt;br /&gt;
ENGINE_free(eng);&lt;br /&gt;
ENGINE_cleanup();&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want an engine to provide all incumbent functionality for the OpenSSL library, then then call &amp;lt;tt&amp;gt;ENGINE_register_complete&amp;lt;/tt&amp;gt; after loading the engine. Incumbent functionality is determined by the manufacturer and includes includes RSA, DSA, DH, ECDH, MD, and RAND operations. See &amp;lt;tt&amp;gt;eng_all.c&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;eng_fat.c&amp;lt;/tt&amp;gt;, and [http://www.openssl.org/docs/crypto/engine.html engine(3)] for details.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ENGINE* eng = ENGINE_by_id(&amp;quot;XXX&amp;quot;);&lt;br /&gt;
if(!(eng-&amp;gt;flags &amp;amp; ENGINE_FLAGS_NO_REGISTER_ALL))&lt;br /&gt;
    ENGINE_register_complete(eng);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cleanup ==&lt;br /&gt;
&lt;br /&gt;
How to cleanup the library arises on occasion. Its often in the context of running a program under a memory checker like Valgrind.&lt;br /&gt;
&lt;br /&gt;
OpenSSL does not provide a &amp;lt;tt&amp;gt;SSL_library_uninit&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;SSL_library_cleanup&amp;lt;/tt&amp;gt; function (also see [http://rt.openssl.org/Ticket/Display.html?id=3824&amp;amp;user=guest&amp;amp;pass=guest Issue #3824, FEATURE: Please provide a function to unintialize the library]). To cleanup the library the library call the following functions:&lt;br /&gt;
&lt;br /&gt;
* FIPS_mode_set(0);&lt;br /&gt;
* ENGINE_cleanup();&lt;br /&gt;
* CONF_modules_unload(1);&lt;br /&gt;
* EVP_cleanup();&lt;br /&gt;
* CRYPTO_cleanup_all_ex_data();&lt;br /&gt;
* ERR_remove_state();&lt;br /&gt;
* ERR_free_strings();&lt;br /&gt;
&lt;br /&gt;
'''Note:''' ERR_remove_state() was deprecated in OpenSSL 1.0.0 when ERR_remove_thread_state() was introduced. ERR_remove_thread_state() was deprecated in OpenSSL 1.1.0 when the thread handling functionality was entirely rewritten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;CRYPTO_cleanup_all_ex_data&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;ERR_remove_state&amp;lt;/tt&amp;gt; should be called on each thread, and not just the main thread.&lt;br /&gt;
&lt;br /&gt;
The above list is a minimum to call. You will still need to cleanup Diffie-Hellman parameters, server contexts, static locks, etc.&lt;br /&gt;
&lt;br /&gt;
After cleanup, you may have some memory leaks due to dynamic allocation of private static variables like &amp;lt;tt&amp;gt;ssl_comp_methods&amp;lt;/tt&amp;gt;. This is a well known issue (see [http://rt.openssl.org/Ticket/Display.html?id=2561&amp;amp;user=guest&amp;amp;pass=guest Issue #2561, Memory leak with SSL built-in compressions]).&lt;br /&gt;
&lt;br /&gt;
== Errata ==&lt;/div&gt;</summary>
		<author><name>Wdtj</name></author>
	</entry>
</feed>