On Thu, May 22, 2025 at 10:51:14PM -0400, Demi Marie Obenour wrote:
> On 5/22/25 22:35, Willy Tarreau wrote:
> > On Thu, May 22, 2025 at 09:49:20PM -0400, Demi Marie Obenour wrote:
> >>> What do you think you would need ? For randoms, what do you qualify
> >>> as strong random numbers for example ?Is it based on the period
> >>> length ? On the way it's seeded ? Right now our PRNG has a 2^128 bits
> >>> period and is seeded from: time, pid, ppid, urandom, RAND_bytes() when
> >>> openssl is available, random(), ASLR, execution time, and host name,
> >>> i.e. about everything we can locally collect that can differ between
> >>> boots and machines.
> >>
> >> "Strong" means "suitable for cryptographic purposes".  The simplest
> >> approach would be to get random numbers directly from OpenSSL, and
> >> to use XChaCha20-Poly1305 with a random nonce for the encryption.
> >> The XChaCha20-Poly1305 nonce is long enough that it can be generated
> >> at random.
> > 
> > Then we'd need a separate strong_random() function that is only
> > available when openssl is enabled.
> 
> On Linux, another option is to just call getrandom() directly, which
> works on any recent kernel.

... and blocks on some of them if lacking entropy at boot. It's only
very recently that it finally adopted a timeout (which is still quite
long by the way). We've had this problem already on some products. I'd
rather seed a secure prng and only rely on it later, this also has the
advantage of being portable.

> >>> And for base64, if the output of the HMAC is of
> >>> fixed size, base64 will be as well, so the part of the string used
> >>> to construct it will be made of only table lookups. If your concern
> >>> is that this property is not guaranteed over time, I can understand,
> >>> but then we could simply add a comment on top of the function to
> >>> mention that the processing time per input byte must remain constant.
> >>
> >> Table lookups are vulnerable to timing attacks, as shown by
> >> Daniel J. Bernstein in 2005 [1].  libsodium has a constant-time
> >> base64 decoder under a permissive license.
> >>
> >> [1]: https://cr.yp.to/antiforgery/cachetiming-20050414.pdf
> > 
> > Thanks for the link. With that said, the attack described above only
> > works because the tables do not fit in a cache line. For base64 the
> > tables are a single cache line (64B).
> 
> Unfortunately, this isn't enough: it turns out that access latency
> can be different even within a cache line.

It will depend on architectures but sometimes that's true.

> > But we could pretty well replace our implementation with a constant
> > time one if needed. From memory we have two implementations, the
> > normal one and a URL-safe one. But do not hesitate to have a look at
> > its replacement. If you need to import a file from libsodium, please
> > place it in src/ for .c, or in include/import/ for .h, and try to
> > change the least possible files there so that it's possible to update
> > from time to time (like we do for xxhash, slz, trees etc). Otherwise
> > if it's just a matter of replacing a function or two, it's OK to
> > just copy them into base64.c, but then please mention in the comment
> > on top of the function where it comes from (both to help check for
> > updates and for crediting the original author).
> 
> That should be doable, though I don't have any immediate plans to do
> this in the near term.

OK!

> >> Is loading a Lua module written in C an option?  Obviously that can't
> >> be done at runtime, but would it make sense to do that at startup?
> > 
> > I know that some do it to extend haproxy, but your C code needs to be
> > careful not to make blocking calls nor to take too much time. That's
> > the problem with calling external code, you need to be certain it was
> > designed with extremely low latency in mind (and the reason why some
> > existing Lua libs are causing problems). I don't know how that fits
> > with lua-load-per-thread by the way.
> 
> Is verifying an asymmetric signature too slow?

Normally not :-)

> lua-load-per-thread is
> the only approach that makes sense here, as you certainly don't want to
> be doing asymmetric cryptography while holding a global lock.

I agree! We'd even like to deprecate lua-load in favor of an explicit
keyword that makes users conscious of the performance impact of the lock.

> > At the very least it can be an option to easily experiment with extra
> > code without having to patch haproxy. Another option for testing is to
> > rely on LD_PRELOAD, but then you need to be super careful to respect
> > the exact internal API and ABI (any build option counts).
> This would be purely a Lua extension, not reliant on any of HAProxy's
> header file.  

In this case that's totally fine.

Willy


Reply via email to