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

Steven D'Aprano steve at pearwood.info
Sat Jun 11 03:40:14 EDT 2016


On Thu, Jun 09, 2016 at 07:52:31PM -0700, Nikolaus Rath wrote:
> On Jun 09 2016, Guido van Rossum <guido at python.org> wrote:
> > I don't think we should add a new function. I think we should convince
> > ourselves that there is not enough of a risk of an exploit even if
> > os.urandom() falls back.
> 
> That will be hard, because you have to consider an active, clever
> adversary.

We know that there are exploitable bugs from Linux systems due to 
urandom, e.g. the Raspberry Pi bug referenced elsewhere in this thread.

https://www.raspberrypi.org/forums/viewtopic.php?f=66&t=126892


> On the other hand, convincing yourself that in practice os.urandom would
> never block unless the setup is super exotic or there is active
> maliciousness seems much easier.

Not that super exotic. In my day job, I've seen processes hang for five 
or ten minutes during boot up, waiting for the OS to collect enough 
entropy, although this was not recently and it wasn't involving Python. 
But VMs or embedded devices may take a long time to generate entropy. If 
the device doesn't have a hardware source of randomness, and isn't 
connected to an external source of noise like networking or a user who 
habitually fiddles with the mouse, it might take a very long time indeed 
to gather entropy...

If I have understood the concensus, I think we're on the right track:

(1) os.urandom should do whatever the OS says it should do, which on 
Linux is fall back on pseudo-random bytes when the entropy pool hasn't 
be initialised yet. It won't block and won't raise.

(2) os.getrandom will be added to 3.6, and it will block, or possibly 
raise, whichever the caller specifies.

(3) The secrets module in 3.6 will stop relying on os.urandom, and use 
os.getrandom. It may provide a switch to choose between blocking and 
non-blocking (raise an exception) behaviour. It WON'T fall back to 
predictable non-crypto bytes (unless the OS itself is completely 
broken).

(4) random will continue to seed itself from os.urandom, because it 
doesn't care if urandom provides degraded randomness. It just needs to 
be better than using the time as seed.

(5) What about random.SysRandom? I think it should use os.getrandom.

(6) A bunch of stuff will happen to make the hash randomisation not 
break when systemd runs Python scripts early in the boot process, but I 
haven't been paying attention to that part :-)

Is this a good summary of where we are at?



-- 
Steve


More information about the Python-Dev mailing list