OpenSSL 1.1 End Of Live

OpenSSL logo

The well known and well established OpenSSL 1.1.1 series will reach End of Life (EOL) on 11th September 2023. So next Monday! :(
Users of OpenSSL 1.1.1 should consider their options and plan any actions they might need to take.

Note that Indy users are still stuck to the OpenSSL 1.0 branch, even 1.1 is not yet officially supported. Some alternate IO handlers are able to use newest releases - to some extend.
Indy users should rather move to a better supported library, like our little mORMot.

Also note that there are some API incompatibilities between 1.1 and 3.x. Functions have been renamed, or even removed; new context constructors appeared; some parameters types even changed!
Our unit tries to address all those problems at runtime, and is tested against several version of the OpenSSL library, to ensure you do not have to worry about those low-level issues.

OpenSSL 3.x Benefits

With OpenSSL 3.0, the developpers did a huge refactoring of the library internals.
To be fair, the 1.x source code of OpenSSL was kind of a mess, and difficult to maintain. The biggest IT companies did even made their own forks or switched to other libraries. The best known is BoringSSL, maintained by Google, and used e.g. in Chrome and Android.
So it was time for a refactoring, especially for a library as critical as OpenSSL for so many projects.

With the new 3.x branch, a lot of low-level API functions have been deprecated.
In practice, you don't have direct access any more to the internal structures of the library, and should now always use the high-level API to access a context property, or execute the processing methods. For instance, the low-level AES_encrypt function is not available any more: from now on, you need to use the high-level EVP_Encrypt* API.
The official Migration Guide page is clearly huge, and worth reading if you want to prepare yourself to the upcoming years with OpenSSL.

OpenSSL 3.0 Performance Regression

The 3.0 branch new code may seem more beautiful and more maintainable, but it had its drawbacks. Newer is not always better.
Most users of this new release observed a huge performance regression when switching from 1.x to 3.0. It affected a lot of projects, from various languages, even script languages which were not already shining about performance. Time regression from 3x up to 10x were reported. On our side, X509 certificates manipulation was really slower than before - the worse being about X509 stores.

Some slowdown were expected and documented (like RSA key generation, which now uses 64 rounds). But the regression was much deeper.
The culprit seems not to be the core cryptographic code, like AES buffer encoding (which asm claims to have been optimized even further on 3.x branch), but the OpenSSL context structures themselves. They were rewritten for future maintainability, but not focusing on their actual performance.

OpenSSL 3.1 Numbers

The 3.1 branch claims to have addressed most of these problems.

The Tortoise and the Hare

To be sure, we run the mORMot cryptographic regression tests with several versions of OpenSSL. And in fact, OpenSSL 3.1 was much faster than OpenSSL 3.0, but still behind OpenSSL 1.1.
Here are the numbers we observed for the whole TTestCoreCrypto method execution, executed on Win32:

  • OpenSSL 1.1 = 15 sec
  • OpenSSL 3.0 = 33 sec
  • OpenSSL 3.1 = 18 sec

There are several aspects to emphasize:

  • Those tests runs also mORMot engine cryptography, so you don't only test OpenSSL: the "pure mORMot" tests take around 4.5 seconds in the above numbers;
  • Any serious project should consider compiling on Win64, and running a server on a x86_64 Linux - on this platform, the regression does exist, but only slightly better;
  • The slowdown was less affecting TTestCoreCrypto.Benchmark (i.e. raw buffer encryption) than TTestCoreCrypto.Catalog (i.e. certificates process);
  • Our tests were mono-threaded, and worse slow down were reported on heavily threaded process (up to x10).

Within the mORMot OpenSSL wrapper, we try to cache as many context as possible. For instance, we don't lookup the OpenSSL algorithm by name for each call, but we cache it at runtime to avoid any slowdown.
But it seems not enough with OpenSSL 3.0, which may affect your application performance.

To Support or Not Support

So OpenSSL 3.1 seems to be the way to go.

On Linux (or other POSIX systems), you are likely to use the library shipped with the system.
So you would not worry about which version to use. And, sadly, it is very likely that your distribution provides OpenSSL 3.0 and not OpenSSL 3.1.

On Windows (or Mac), you could (should?) use your "own" dll/so files, so you have to take into account the support level of the library.

  • OpenSSL 3.0 is a Long Term Support (LTS) version, which will be maintained until 7th September 2026.
  • OpenSSL 3.1 will be supported only until 14th March 2025.

These support end dates could appear counter-intuitive, but this is an usual way in Open Source projects, the best known being perhaps Ubuntu LTS versions.
For more information about OpenSSL support lifetime, look at the official OpenSSL Downloads page.

So, for most projects, especially on Windows where you are likely to publish OpenSSL dll with your own executable, switching to OpenSSL 3.1 is likely to be the way to go.
If you need to gather some security certification for your product, you may consider using OpenSSL 3.0 LTS version, which may help your certification remain active for a longer period.

Any feedback is welcome on our forum, as usual!