|Deletions are marked like this.||Additions are marked like this.|
|Line 38:||Line 38:|
|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.||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 there.|
arc4random(3) is random-number-generating library function, first available on BSD platforms, and also on GNU/Linux with libbsd.
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...
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.
and is also used within the kernel:
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 there.
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.
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:
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.