> On Jun 11, 2016, at 11:34 AM, Guido van Rossum <gu...@python.org> wrote:
> 
> In terms of API design, I'd prefer a flag to os.urandom() indicating a 
> preference for
> - blocking
> - raising an exception
> - weaker random bits

If os.urandom can’t block on Linux, then I feel like it’d be saner to add 
os.getrandom(). I feel like these flags are going to confuse people, 
particularly when you take into account that all 3 of them are only going to 
really matter on Linux (and particularly on newer Linux) and for things like 
“blocking” it’s going to get confused with the blocking that /dev/random does 
on Linux.

Right now there are two ways to access the system CSPRNG on *nix, there is 
/dev/urandom pretty much always, and then there is getrandom() (or arc4random, 
etc, depending on the specific OS you’re on). 

Perhaps the right answer is to go back to making os.urandom always 
open(“/dev/urandom”).read() instead of trying to save a FD by using getrandom() 
and just add os.getrandom() which will interface with 
getrandom()/arc4random()/etc and always in blocking mode. Why always in 
blocking mode? Because it’s the only way to get consistent behavior across 
different platforms, all non Linux OSs either block or they otherwise ensure 
that it is initialized prior to it even being possible to access the CSPRNG.

Using this, code can be smarter about what to do in edge cases than we can 
reasonably be in os.urandom, for example see 
https://bpaste.net/show/41d89e520913 <https://bpaste.net/show/41d89e520913>.

The reasons I think this is preferable to adding parameters to os.urandom are:

* If we add parameters to os.urandom, you can’t feature detect their existence 
easily, you have to use version checks.
* With flags, unless we add even more flags we can’t dictate what should happen 
if we’re on a system where the person’s desired preference can’t be satisfied. 
We either have to just silently do something that may be wrong, or add more 
flags. By adding two functions people can pick which of the following they want 
with some programming (see example):

    * Just try to get the strongest random, but fall back to maybe not random 
if it’s early enough in boot process.
    * Fail on old Linux rather than possibly get insecure random.
    * Actually write cross platform code to prevent blocking (since only Linux 
allows you to not block)
        * Fail hard rather than block if we can’t get secure random bytes 
without blocking.
        * Soft fail and get “probably good enough” random from os.urandom on 
Linux.
        * Hard fail on non Linux if we would block since there’s no 
non-blocking and “probably good enough” interface.
        * Soft fail and get “probably good enough” random from os.urandom on 
Linux, and use time/pid/memory offsets on non Linux.
    * Just use the best source of random available to use on the system, and 
block rather than fail.

I don’t see any way to get the same wide set of options by just adding flags to 
os.urandom unless we add flags that work for every possible combination of what 
people may or may not want to.

—
Donald Stufft



_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to