[PATCH] arc4random implementation
Florian Weimer
fweimer@redhat.com
Thu May 31 13:57:00 GMT 2018
The attached patch provides an implementation of arc4random,
arc4random_buf, and arc4random_uniform.
I believe it is reasonably complete, except for the documentation. I
will submit that part once Zack's cryptography changes have been added
to the manual, to avoid conflicts. More statistical tests would make
sense as well, but the tricky part will be to weigh run time of the test
against an extremely low false positive rate (e.g., a one-in-1024 chance
of failure, as it happens with some statistical tests, would not be
acceptable).
For fork detection, there are two modes, depending on the availability
of MADV_WIPEONFORK support in the kernel.
The MADV_WIPEONFORK implementation is much simpler and has the advantage
that it avoids deadlocks even if direct clone/fork system calls are
performed in multi-threaded processes. It also avoids repeated mmap
calls, which can fail due to OOM.
The fallback implementation uses two counters (one in a MAP_PRIVATE
mapping, one in a MAP_SHARED mapping) for fork detection. It relies
heavily on locking. Direct fork/clone system calls from multi-threaded
processes can result in deadlocks, but the detection algorithm was
designed in such a way that it would still work with such direct system
calls. stdlib/arc4random-forkdetect.c and
stdlib/tst-arc4random-forkdetect.c have the gory details.
As the source for randomness, the Linux getrandom system call, a CPU
randomness source, and /dev/urandom are used, in that order. The idea
is to give the kernel a chance to implement a particular randomness
policy, before switching to the CPU generator. The /dev/urandom
fallback is a bit of a wart and may of course fail in a chroot
environment, but I don't see a way to avoid it.
Since arc4random cannot report failure, there are various situations in
which the process may be terminated in response to calling arc4random
(OOM, lack of /dev/urandom). For this reason, it is currently not
advisable to use this implementation within glibc itself. If we want to
change that, we need to perform the first seed using AT_RANDOM, which is
always available (unlike getrandom or /dev/urandom).
The implementation has sysdeps hooks for the randomness generation
(kernel and CPU) and the AES key schedule and block operation (CPU
only). As a proof of concept, the CPU parts are implemented for x86.
(These parts could conceivably be committed separately.)
The generator will not pass certification due to lack of periodic
reseeding and backtrack protection. Adding reseeding should be easy
enough in a follow-up patch. Efficient backtrack protection would
probably need per-thread key schedules, so around 160 extra bytes of TLS
data. It also needs more frequent reseeding. I think these aspects
could be corrected in response to a review for certification, if that
ever happens.
Thanks,
Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: arc4random.patch
Type: text/x-patch
Size: 142481 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20180531/17163f00/attachment.bin>
More information about the Libc-alpha
mailing list