The State of SSL Stacks

haproxy.com

144 points by zdw 7 days ago


jaas - 3 days ago

> We also tested Rustls and its rustls-openssl-compat layer. Rustls could be an interesting library in the future, but the OpenSSL compatibility application binary interface (ABI) was not complete enough to make it work correctly with HAProxy in its current state.

Rustls is actively working on improving the OpenSSL compatibility layer. Hopefully we'll have it fully working for HAProxy soon!

We've also invested a lot in performance. Next week we'll be publishing a blog post about Rustls server side performance. Since it's relevant to discussions about TLS stack performance, here's a preview:

https://docs.google.com/document/d/1xFoRjb7pn4ZtL5BH7_ZwXNgN...

c0l0 - 3 days ago

Wow... reading this article in full really made me lose hope in OpenSSL, the project and the library.

I was well aware of the expected inconveniences any new major OpenSSL release would trigger (esp. older, less actively maintained applications having to adapt their API usage to keep working) going in, but what the linked github issue/PR comments hint at is just... mental.

As best illustrated by https://github.com/openssl/openssl/issues/20286#issuecomment... not only seem the core developers not care about runtime performance at all, they also seem to have a completely absurd perception of their own project, esp. in relation to other, genuinely small FOSS projects.

It's just wild. I hope this can still be turned around, and OpenSSL can somehow re-emerge from this clusterfuck as the stable bedrock of web transport security that we learned to rely on from 2014 onwards.

pixelesque - 3 days ago

I've been working on a project of mine which makes web requests via libCURL, and the number of memory allocations OpenSSL makes for a single TLS connection is astonishing - running it through `heaptrack` was a real eye-opener.

Discussion I found about other people mentioning it:

https://github.com/openssl/openssl/discussions/26659

In some cases (not all) for my workflows perf record traces show the allocation / deallocation overhead is quite significant, especially in a multi-threaded setup, where contention against the system allocator starts to become a problem in some situations.

dur-randir - 3 days ago

For anyone wondering, have fun reading responses to those:

- https://github.com/openssl/openssl/issues/20286

- https://github.com/openssl/openssl/issues/18814

- https://github.com/openssl/openssl/issues/16791

- https://github.com/openssl/openssl/issues/17950

kccqzy - 3 days ago

I have no idea this happened, but after reading this article my main takeaway was that OpenSSL shot themselves in the foot. Is this a fair assessment? I mean the excessive locking just stands out to be ill-advised for this performance-sensitive piece of code.

2bluesc - 3 days ago

Never heard of aws-lc before this, but now I'm looking for an excuse to use it.

drob518 - 2 days ago

Well, that was an extremely thorough and well-documented take down of OpenSSL’s issues, both technical and organizational. The OpenSSL team should be embarrassed. What’s your side of the story, OpenSSL?

DyslexicAtheist - 3 days ago

> Modern implementations must support a range of TLS protocol versions (from legacy TLS 1.0 to current TLS 1.3)

So this statement is strange considering "modern" security standards either nudge you (or demand) to deprecate anything that isn't v1.3 or v1.2.

If the implementation is "modern" why would I allow 1.0 ?

This seems like a HA-Proxy problem. They ought to maintain support for geriatric TLS versions on a dedicated release branch connected to a support-model that nudges their client into updating by increasing their fees for maintaining that system. Not doing so means the vendor is part of the problem why we have slower adoption rates for 1.3 than we could otherwise have.

It would have been cool to see AWS's s2n-tls (or s2n-quic https://github.com/aws/s2n-quic) included in their benchmark.

One of my all time favorite episode from the SCW podcast goes into the design decisions of s2n:

The feeling's mutual: mTLS with Colm MacCárthaigh https://securitycryptographywhatever.com/2021/12/29/the-feel...

From AWS: https://aws.amazon.com/security/opensource/cryptography/

> "In 2015, AWS introduced s2n-tls, a fast open source implementation of the TLS protocol. The name "s2n", or "signal to noise," refers to the way encryption masks meaningful signals behind a facade of seemingly random noise. Since then, AWS has launched several other open source cryptographic libraries, including Amazon Corretto Crypto Provider (ACCP) and AWS Libcrypto (AWS-LC). AWS believes that open source benefits everyone, and we are committed to expanding our cryptographic and transport libraries to meet the evolving security needs of our customers."

Here is a pdf that provides some performance results for s2n (sadly not s2n-quic):

"Performance Analysis of SSL/TLS Crypto Libraries: Based on Operating Platform" https://bhu.ac.in/research_pub/jsr/Volumes/JSR_66_02_2022/12...

jedisct1 - 2 days ago

Official OpenSSL benchmarks: https://openssl-library.org/performance.html

OpenSSL 3.0 was catastrophic, but it looks like OpenSSL 3.5 isn't too bad.

jeffbee - 3 days ago

It seems weird to disqualify boringssl due to live-at-head project philosophy. Obviously _your_ project doesn't have to change every time boringssl changes.

toast0 - 3 days ago

> Roman Arutyunyan from NGINX core team were the first to propose a solution with a clever method that abuses the keylog callback to make it possible to extract or inject the required elements, and finally make it possible to have a minimal server-mode QUIC support.

This sounds like future pain waiting to happen. My experience with callbacks in Openssl 1.0.x is that letter releases may significantly alter or remove callbacks. In the long term, I guess it worked out, because I figured out a better way to do what I was trying to do and got it accepted into OpenSSL and that fixed things for everyone, but in the short term it was a PITA and I'd have to decide between out of date OpenSSL with my feature working and updating OpenSSL to address whatever security problem of the day but my feature not working while I take a week to figure out how to do it in the new world.

In my case, the feature was doing DHE-RSA with Microsoft Schannel and not causing an 'out of memory' error on the client when the server public key has 8 or more bits of zeros at the high end. The client didn't actually run out of memory, but that was the error it reported.

Multithreading can be hard; when I had a problem for HAProxy to solve, 1.8 was just out and using multiple processes was much better for my application than threads. Configuration for multiple processes was more difficult, of course, but one time pain in order to get many multiples of throughput was worth it (and I didn't need any shared state between processes, so I didn't lose functionality... not everyone has that liberty) But I gather multithreaded HAProxy has gotten a lot better; and my problem went away and anyway I left the company whose problem I was solving with HAProxy anyway; so I don't have current knowledge. But the description of OpenSSL is describing a multithreading nightmare:

> With OpenSSL 3.0, an important goal was apparently to make the library much more dynamic, with a lot of previously constant elements (e.g., algorithm identifiers, etc.) becoming dynamic and having to be looked up in a list instead of being fixed at compile-time. Since the new design allows anyone to update that list at runtime, locks were placed everywhere when accessing the list to ensure consistency. These lists are apparently scanned to find very basic configuration elements, so this operation is performed a lot.

I'm not sure this kind of thing needs to be a fixed list at compile time (although it has worked for decades, yeah?); having a way to load a config and fixing the config before sharing it would be a good way to avoid the need for locking. If it does need to be changable at runtime, it can still be done with performance... an instance of configuration should be immutable, then you can have a shared pointer to the current config. At critical points, you might copy the current pointer or something. There's techniques and prior art for this kind of stuff.

Ros23 - 2 days ago

LibreSSL is the answer.

edelbitter - 3 days ago

[flagged]

yencabulator - 2 days ago

The State of C SSL Stacks