328
Comment: new page
|
3763
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
= arc4random = arc4random(3) is random-number-generating library function, first available on BSD platforms, and also on GNU/Linux with libbsd. |
arc4random(3) is random-number-generating library function, first available on BSD platforms, and also on GNU/Linux with [[https://tracker.debian.org/libbsd|libbsd]]. |
Line 6: | Line 4: |
Line 7: | Line 6: |
Line 8: | Line 8: |
Line 9: | Line 10: |
== Implementations == arc4random(3) initialises itself with some random bytes from the kernel, but rather than returning those bytes directly, a stream cipher is used to produce longer streams of output. Re-seeding happens occasionally thereafter. The intention was to avoid the overhead of making a system call, on each call to arc4random(3) The function when originally implemented in OpenBSD, used the RC4 cipher to produce the output stream. OpenBSD now uses a !ChaCha20 stream cipher. If a process forks, it should re-seed itself to avoid each process sharing the same RNG state. OpenBSD uses the mmap(2) INHERIT_ZERO flag to reliably detect forks, and then re-seed. FreeBSD makes a system call to getpid(2) to detect forking, but that means the overhead of its arc4random(3) may be worse than if the RC4 cipher wasn't being used there at all... https://lists.freebsd.org/pipermail/freebsd-security/2014-July/007849.html FreeBSD's libc still uses RC4 libkern/arc4random.c, but discards the first 1024 bytes of the stream cipher's output, to try to mitigate known weaknesses in the cipher. https://svnweb.freebsd.org/base/head/lib/libc/gen/arc4random.c?view=markup and is also used within the kernel: https://svnweb.freebsd.org/base/head/sys/libkern/arc4random.c?view=markup libbsd provides an arc4random(3), previously using RC4 but this was changed to !ChaCha20 in version 0.8.0 (Debian package version 0.8.0-1). GNU libc's atfork can be used to reliably detect forking. GNU/kFreeBSD provides only the libbsd implementation. == Embedded code copies == OpenBSD bundles implementations of arc4random, getentropy etc. in their 'portable' releases of: LibreSSL, OpenNTPd, OpenSMTPd, OpenSSH, signify. We should be consult with them before changing anything. Embedded copies of this code can also be [[https://codesearch.debian.net/search?perpkg=1&q=_rs_stir|found]] in: * atheme-services - uses !ChaCha20, suffers issues 2, 3 described below * getdns - uses !ChaCha20, suffers issue 2 described below * ncrack - uses !ChaCha20, suffers issue 2 described below * newlib - uses !ChaCha20; unclear how it detects forking * pureftpd - uses !ChaCha20, suffers issues 2, 3 described below * unbound - uses !ChaCha20, suffers issue 2 described below; FTBFS on kfreebsd, hurd because getentropy implementations are missing Similar code to arc4random(3) can also be found in libevent. == Issues == 1. RC4 is not considered to be a cryptographically strong cipher any more. 1a. Some implementations using RC4, discard the first 1KByte of more of the keystream as a possible countermeasure, but some did not even do this. 2. Some implementations don't re-seed reliably (or perhaps at all) when a process forks. MAP_INHERIT_ZERO is reliable, but only available on OpenBSD. atfork functions are the best thing available on most other platforms. getpid is slowest (requiring a syscall on every iteration), and there are edge cases where it doesn't work: https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux 3. Some methods of seeding are unsafe, and failures cannot be indicated to the caller. In a chroot/jail environment, perhaps /dev/urandom is missing. Or if all file descriptors are exhausted, nothing can be read from there. OpenBSD and FreeBSD provide system calls that are guaranteed to not fail. |
arc4random(3) is random-number-generating library function, first available on BSD platforms, and also on GNU/Linux with libbsd.
Manual pages
http://man.openbsd.org/?query=arc4random
https://www.freebsd.org/cgi/man.cgi?query=arc4random
https://manpages.debian.org/cgi-bin/man.cgi?query=arc4random
Implementations
arc4random(3) initialises itself with some random bytes from the kernel, but rather than returning those bytes directly, a stream cipher is used to produce longer streams of output. Re-seeding happens occasionally thereafter. The intention was to avoid the overhead of making a system call, on each call to arc4random(3)
The function when originally implemented in OpenBSD, used the RC4 cipher to produce the output stream. OpenBSD now uses a ChaCha20 stream cipher.
If a process forks, it should re-seed itself to avoid each process sharing the same RNG state. OpenBSD uses the mmap(2) INHERIT_ZERO flag to reliably detect forks, and then re-seed.
FreeBSD makes a system call to getpid(2) to detect forking, but that means the overhead of its arc4random(3) may be worse than if the RC4 cipher wasn't being used there at all...
https://lists.freebsd.org/pipermail/freebsd-security/2014-July/007849.html
FreeBSD's libc still uses RC4 libkern/arc4random.c, but discards the first 1024 bytes of the stream cipher's output, to try to mitigate known weaknesses in the cipher.
https://svnweb.freebsd.org/base/head/lib/libc/gen/arc4random.c?view=markup
and is also used within the kernel:
https://svnweb.freebsd.org/base/head/sys/libkern/arc4random.c?view=markup
libbsd provides an arc4random(3), previously using RC4 but this was changed to ChaCha20 in version 0.8.0 (Debian package version 0.8.0-1). GNU libc's atfork can be used to reliably detect forking.
GNU/kFreeBSD provides only the libbsd implementation.
Embedded code copies
OpenBSD bundles implementations of arc4random, getentropy etc. in their 'portable' releases of: LibreSSL, OpenNTPd, OpenSMTPd, OpenSSH, signify. We should be consult with them before changing anything.
Embedded copies of this code can also be found in:
atheme-services - uses ChaCha20, suffers issues 2, 3 described below
getdns - uses ChaCha20, suffers issue 2 described below
ncrack - uses ChaCha20, suffers issue 2 described below
newlib - uses ChaCha20; unclear how it detects forking
pureftpd - uses ChaCha20, suffers issues 2, 3 described below
unbound - uses ChaCha20, suffers issue 2 described below; FTBFS on kfreebsd, hurd because getentropy implementations are missing
Similar code to arc4random(3) can also be found in libevent.
Issues
1. RC4 is not considered to be a cryptographically strong cipher any more.
1a. Some implementations using RC4, discard the first 1KByte of more of the keystream as a possible countermeasure, but some did not even do this.
2. Some implementations don't re-seed reliably (or perhaps at all) when a process forks. MAP_INHERIT_ZERO is reliable, but only available on OpenBSD. atfork functions are the best thing available on most other platforms. getpid is slowest (requiring a syscall on every iteration), and there are edge cases where it doesn't work:
https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux
3. Some methods of seeding are unsafe, and failures cannot be indicated to the caller. In a chroot/jail environment, perhaps /dev/urandom is missing. Or if all file descriptors are exhausted, nothing can be read from there. OpenBSD and FreeBSD provide system calls that are guaranteed to not fail.