2023-09-08

End Of Live OpenSSL 1.1 vs Slow OpenSSL 3.0

You may have noticed that the OpenSSL 1.1.1 series will reach End of Life (EOL) next Monday...
Most sensible options are to switch to 3.0 or 3.1 as soon as possible.

mormotSecurity.jpg, Sep 2023

Of course, our mORMot 2 OpenSSL unit runs on 1.1 and 3.x branches, and self-adapt at runtime to the various API incompatibilities existing between each branch.
But we also discovered that switching to OpenSSL 3.0 could led into big performance regressions... so which version do you need to use?

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!

2023-09-06

Meet at EKON 27

EKON27.png, Sep 2023

There is still a bit more than one day left for "very early birds" offer for EKON 27 conference in Germany, and meet us for 3 sessions (including a half-day training/introduction to mORMot 2)!

EKON27.png, Sep 2023

Join us the 6-8th of November in Düsseldorf!

Continue reading

2023-08-24

mORMot 2.1 Released

We are pleased to announce the release of mORMot 2.1.
The download link is available on github.

The mORMot family is growing up. :)

Continue reading

2023-07-20

The LUTI and the mORMot

RegressTests.png, Jul 2023

Since its earliest days, our mORMot framework did offer extensive regression tests. In fact, it is fully test-driven, and almost 78 million individual tests are performed to cover all its abilities:

RegressTests.png, Jul 2023

We just integrated those tests to the TranquilIT build farm, and its great LUTI tool. So we have now continuous integration tests over several versions of Windows, Linux, and even Mac!
LUTI is the best mORMot's friends these days. :)

Continue reading

2023-05-05

New DNS and (C)LDAP Clients for Delphi and FPC in mORMot 2

DNS and LDAP are the two protocols on which the Internet and the Intranet are built.
Most of the time, you don't have to care about them. But sometimes, you need to access them directly, especially in a corporate environment.

We just introduced in our Open Source mORMot 2 framework two client units to access DNS and LDAP/CLDAP servers.
You can resolve IP addresses and services using DNS, and ask for information about your IT infrastructure using LDAP.

Continue reading

2023-04-19

New Command Line Parser in mORMot 2

For most projects, we want to be able to pass some custom values when starting it.
The command line is then used to add this additional information.

We have ParamStr and ParamCount global functions, enough to retrieve the information. You may also use FindCmdLineSwitch for something more easy to work with.
The Lazarus RTL offers some additional methods like hasOption or getOptionValue or checkOptions in its TCustomApplication class. Their are better, but not so easy to use, and not available on Delphi.

We just committed a new command line parser to our Open Source mORMot 2 framework, which works on both Delphi and FPC, follows both Windows and POSIX/Linux conventions, and has much more features (like automated generation of the help message), in an innovative and easy workflow.

Continue reading

2023-01-10

mORMot 2 Release Candidate

The mORMot 2 framework is about to be released as its first 2.0 stable version.

The framework feature set should now be considered as sealed for this release.
There is no issue reported still open at github or in the forum.

Please test it, and give here some feedback to fix any problem before the actual release!
We enter a framework code-freeze phase until then.
:-)

Continue reading

2022-12-28

Efficient Routing for Christmas

This is perhaps the last new feature of mORMot 2 before its first stable release: a very efficient custom URI routing for our HTTP/HTTPS servers.

At ORM and SOA level, there is by-convention routing of the URI, depending on the ORM table, SOA interface and method, and TOrmModel.Root value. Even for our MVC web part, we rely on a /root/ URI prefix, which may not be always needed.
Relying on convention is perfect between mORMot clients and servers, but in some cases, it may be handy to have something smoother, e.g. to publish a truly REST scheme.

We introduced two routing abilities to mORMot 2, with amazing performance (6-12 million parsings per CPU core), via a new THttpServerGeneric.Route property:

  • Internal URI rewrite, to redirect internally from a human/REST-friendly request e.g. to a SOA /root/interface.method layout, or to a MVC web page;
  • Direct callback execution, with optional parameter parsing.

Article edited on 28th December:
Fixed performance numbers (much higher than reported), and introduced latest source changes.

Continue reading

- page 1 of 50