[Python-Dev] BDFL ruling request: should we block forever waiting for high-quality random bits?

Guido van Rossum guido at python.org
Sat Jun 11 16:48:49 EDT 2016

On Sat, Jun 11, 2016 at 12:53 PM, Larry Hastings <larry at hastings.org> wrote:

> On 06/11/2016 11:30 AM, Donald Stufft wrote:
> The problem is that someone writing software that does
> os.urandom(block=True) or os.urandom(exception=True) which gets some bytes
> doesn’t know if it got back cryptographically secure random because Python
> called getrandom() or if it got back cryptographically secure random
> because it called /dev/urandom and that gave it secure random because it’s
> on a platform that defines that as always returning secure or because it’s
> on Linux and the urandom pool is initialized or if it got back some random
> bytes that are not cryptographically secure because it fell back to reading
> /dev/urandom on Linux prior to the pool being initialized.
> Let me jump in tangentially to say: I think os.urandom(block=True) is
> simply a bad API.  On FreeBSD and OpenBSD, /dev/urandom may block, and you
> don't have a choice.  On OS X, /dev/urandom will never block, and you don't
> have a choice.  In Victor's initial patch where he proposed it, the flag
> was accepted on all platforms but only affected its behavior on Linux and
> possibly Solaris.  I think it's bad API design to have a flag that seems
> like it would be meaningful on multiple platforms, but in practice is
> useful only in very limited circumstances.  If this were old code, or
> behavior we inherited from the platform and we were making the best of a
> bad situation, that'd be one thing.  But this is a proposed new API and I
> definitely think we can do better.
> As I understand the proposed semantics for os.urandom(exception=True), I
> feel it falls into the same trap though not to the same degree.
> Of course, both flags break backwards-compatibility if they default to
> True, and I strongly disagree with .
> It's far better in my opinion to keep the os module as a thin shell over
> platform functionality.  That makes Python's behavior more predictable on a
> platform-by-platform basis.  So I think the best approach here is to add
> os.getrandom() as a thin shell over the local getrandom() (if any).

OK, the flags are unpopular, so let's forget about them.

But I find an os.getrandom() that only exists on those (few?) platforms
that support it a nuisance too -- this just encourages cargo cult code
that's unnecessarily complicated and believed to be secure without anybody
ever verifying.

I'd like to consider what people freak out about.

- You could freak out about blocking

- You could freak out about getting slightly less random bits

- You could freak out about supporting Python 3.5 and earlier

- You could freak out about supporting all platforms

You could also freak out about combinations of the above, but that gets
complicated and you should probably consider that you're over-constraining
matters. If you freak out about all at once (or both the first and the
second bullet) you should consider a career change.

If you don't freak out about any of these (meaning you're happy with Python
3.6+) you should use the secrets module.

If you freak out about support for older Python versions, try the secrets
module first and fall back to os.urandom() -- there really isn't any other

If you freak out about getting slightly less random bits you should
probably do a complete security assessment of your entire stack and fix the
OS and Python version, and use the best you can get for that combination.
You may not want to rely on the standard library at all.

If you freak out about blocking you're probably on a specific platform, and
if that platform is Linux, you're in luck: use os.urandom() and avoid
Python 3.5.0 and 3.5.1. On other platforms you're out of luck.

So I still don't see why we need os.getrandom() -- it has nothing to
recommend it over the secrets module (since both won't happen before 3.6).

So what should the secrets module use? Let's make that part an extension

--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20160611/b18ff4fb/attachment.html>

More information about the Python-Dev mailing list