https://issues.dlang.org/show_bug.cgi?id=16493

          Issue ID: 16493
           Summary: Request for an OS-independent interface to access
                    cryptographically secure pseudo random number
                    generators
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: phobos
          Assignee: nob...@puremagic.com
          Reporter: ajid...@gmail.com

Currently, phobos provides no way to gain platform-independent access to the
operating system's cryptographically secure random number generator.

Such generators are fed with entropy stemming from random hardware events such
as interrupt timing that only the kernel has access to, so most operating
systems implement an API to get random numbers from it.

The current lack of easy CSPRNG access means that developers may make poor
security choices out of either laziness or portability concerns.[1]

CSPRNGs are needed in any function where there is a need for sufficiently
random data in the face of an attacker willing to invest time and effort into
predicting RNG states. This includes uses such as generating password reset
tokens, or generating cryptographic keys. If one does not use a CSPRNG for
password reset tokens, a malicious third party could predict a password reset
token it triggered by sending itself a couple and thus figuring out what the
PRNG state is using off-the-shelf tools.

The implementation varies from platform to platform.

On Linux:
---------

For kernel versions below Linux 3.17, random data can be read from
/dev/urandom. However, /dev/urandom is not guaranteed to be initialised with
sufficient entropy early during the boot process. While many distributions
restore the previous RNG state into it and architectures such as x86 usually
provide enough entropy during boot for this to not be a big problem, embedded
platforms might not do so.

However, with kernel 3.17, a new syscall getrandom[2] was added. It allows to
block until at least 128 bits of entropy have been collected. It also does not
require to use a file descriptor, so random data can be acquired even if the
system is running out of fds (such as if an application doing encryption is on
a system that is under attack to try and starve it of fds).

The use of /dev/random on Linux is not needed (I'd link the talk about it if I
could find it at the moment). Essentially, /dev/random's wacky entropy-counting
and blocking is not what most (if not all) applications want, and does not add
any security unless you're talking about early boot (in which case it would do
the same as getentropy if getentropy was to block for initial seeding).

On Windows:
-----------

Windows offers an API to request CSPRNG data with CryptGenRandom[3]. First, a
CSP needs to be acquired, and the CSP needs to be destroyed after we're done
with it.

On OpenBSD:
-----------

OpenBSD has a syscall called getentropy[4], which inspired the Linux getrandom
syscall. getentropy does not allow requests for more than 256 bytes of data at
a time. However, it might also be sensible to use arc4random[5], it seems.
Python has a os.urandom module, maybe check what they do.

On other POSIX:
---------------

Reading from /dev/random is probably a good fallback for systems such as OS X.
I'm not sure what FreeBSD provides, but apparently it also has a /dev/urandom.
Someone please investigate.

Other OSes:
-----------

Fail loud and proud.

[1] https://github.com/brendanmckenzie/scrypt/issues/1
[2] https://lwn.net/Articles/605828/
[3]
https://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx
[4] http://man.openbsd.org/getentropy.2
[5] http://man.openbsd.org/arc4random.3

--

Reply via email to