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