[openssl-users] Guidance on proper usage of OpenSSL_add_all_digests

Jeffrey Walton noloader at gmail.com
Wed Mar 2 18:48:38 UTC 2016


On Wed, Mar 2, 2016 at 12:27 PM, Neptune <pdrotter at us.ibm.com> wrote:
> Using OpenSSL 1.0.1l
>
> I just learned the painful way that OpenSSL_add_all_digests() is not a
> thread-safe function. I had been calling this in the constructor of a class
> providing hash functions for multiple threads. My question is, how do I know
> if a thread instantiating my class has called OpenSSL_add_all_digests() or
> not? Is there a way to query OpenSSL for the state of the table? Perhaps
> more importantly, is it a requirement to call this function at all? My test
> application seems quite happy to do SHA1 hashes without calling any of the
> *add_all* functions :-/
>

Generally you want to provide initialization on the primary thread
during program startup. That's when you do things like installing the
locks, too. OpenSSL 1.1.0 adds OPENSSL_init_ssl, but its not clear to
me if it allows you to query subsystem initialization.

You can perform initialization in a static C++ ctor, but it can be
tricky because the C++ committee has never addressed the problem of
initialization order across translation units. Also see What's the
"static initialization order fiasco"?
(http://www.parashift.com/c++-faq/static-init-order.html).

Because of gaps in the C++ language, I usually do it in a c++ class
ctor, but the object resides in main(). On the occasions that the C++
class is instantiated as a static object, I use two techniques to
ensure the order of initialization. The first is object file ordering.
The second is compiler attributes, like "__attribute__ ((init_priority
(250)))" (with Clang/GCC/ICC) and "#pragma init_seg({user | lib})"
(with MSVC).

Unfortunately, there is no reasonable way to audit c++ static
constructor order for quality assurance purposes. Also see How to
verify init_priorty for C++ static object initialization order?
(http://sourceware.org/ml/binutils/2015-09/msg00173.html) on the
Binutils mailing list.

Regardless of how you do it, this is what you want to do:
https://wiki.openssl.org/index.php/Library_Initialization. The short
of this is call the following two functions:

  * SSL_library_init()
  * SSL_load_error_strings()

Finally, for the crypto components, like SHA... I don't believe they
need explicit initialization unless you are doing something like
changing the default implementation from software to an engine. The
SSL part of the library allows you to explicitly add selected
algorithms to control what algorithms are used in that portion of the
library.

Jeff


More information about the openssl-users mailing list