[PATCH] getrandom: new applet

Rob Landley rob at landley.net
Tue Jul 5 02:23:31 UTC 2016


On 07/04/2016 11:08 AM, Etienne Champetier wrote:
> 2016-07-04 17:02 GMT+02:00 Denys Vlasenko <vda.linux at googlemail.com>:
>> On Mon, Jul 4, 2016 at 11:00 AM, Etienne Champetier
>> <champetier.etienne at gmail.com> wrote:
>>>> BTW, I know that security people would scream bloody murder,
>>>> but wouldn't
>>>>
>>>> cd /proc && cat cpuinfo meminfo stat interrupts diskstats slabinfo
>>>> schedstat buddyinfo >/dev/random
>>>>
>>>> in practice work quite satisfactorily for adding some entropy at boot time?
>>>
>>> Your cat /proc/* will be almost identical each boot,
>>
>> Yes, at boot it is somewhat likely, although I'd like someone
>> to experiment on a real system.
> 
> I will repeat myself,

Yes, you have been.

> in crypto you prove that it's safe, not the other way around

This is not the main objection.

Linux has provided /dev/random and /dev/urandom for a couple decades
now. One blocks when its internal accounting believes it hasn't got
sufficient entropy to be NSA-proof unpredictable, the other provides
pseudo-rng output that's continually reseeded from /dev/random when
there's entropy there.

Now there's a new API that's a system call rather than reading from the
/proc file. It is drawing from the same pool, and using the same
block/nonblock logic for entropy accounting.

You've implied that this new API can block until it's initialized, which
reading from /dev/random can already do, and presumably
select/poll/inotify could do on /dev/random without consuming entropy. I
gave a trivial command line example allowing an init script to block
waiting for the entropy pool to be initialized, with a timeout that
continues on after a reasonable time period if it isn't. Yes it read one
byte from the entropy pool because it was off the top of my head and I
didn't want to look at the inotifyd --help output and experiment to make
sure that's wired up because in the past 15 years it's never been a
_problem_ for me.

You've _also_ implied that this new API can provide "good enough" random
information before the random pool is initialized, which is what
/dev/urandom is for. You've implied that your new function call is
somehow superior to /dev/urandom because you're magically generating
entropy when the entropy pool is empty, in userspace, somehow. (This is
probably what set people going "you can cat /proc/stuff to /dev/random
to feed crap into it and make it think it's got entropy which is at
least machine-local". Ways of dealing with an empty entropy pool.)

You have NOT explained what the point of your new interface is, what it
does that the existing one CAN'T do, or why it demands a new command
line utility. You haven't even justified the lower bar of modifying
existing C users (such as the shell's $RANDOM) to use the new API
instead. What is the POINT of your requested change?

Your objection here seems to be that the unix "everything is a file"
interface is inefficient. That Plan 9 had the wrong idea and we should
all be using ioclts the way windows intended.

A similar move over in the ps space is https://lwn.net/Articles/633622/
but they aren't proposing providing a "newps" command with a different
command line interface because API. They aren't expecting _users_ (such
as $RANDOM in the shell) to make this difference visible to end users.

Why are you doing so? You may _have_ a reason, but you have yet to
communicate it.

> Maybe kernel maintainers have good reasons to not mix them ...

This is called an "appeal to authority", and you're doing it really
badly. You haven't got an argument so you say 4 out of 5 doctors prefer
your brand of gum, or it was endorsed by a celebrity spokesmodel. That
is not a REASON.

The kernel maintainers added a vdso page with nonblocking userspace
gettimeofday() because it was lower latency than the system call. They
did not change the libc API for it, nor did anyone change the userspace
utilities because of this. Maybe they cared about latency here, I don't
know. That would be an example reason for them to merge it which would
NOT be a reason to create a new command line utility to use it.

It is not OUR job to figure out this "maybe". You are arguing for a
change. If the kernel maintainers had good reasons, link us to their
explanation here.

>> BTW, add to that /proc/net/*. I mean, literally every file (unlike /proc/*,
>> where you don't want to read everything, "kcore" for one may be "a bit" big).
>> There are ~50 files in /proc/net/.
>> Just one example. /proc/net/unix has Inode column for unix sockets.
>> Those depend on the order how processes have started at boot.
>> If there is at least some concurrency, inodes will contain some randomness.
> 
> Network and radio can add some entropy,

Externally visible entropy, if you're up against our out-of-control spy
agencies it doesn't necessarily help. (Although if they can park a block
away and point a yagi antenna at your router there's all sorts of fun
info they can get out of it if you haven't put the sucker in a farraday
cage.)

Sigh, my grandfather worked for the NSA for 40 years (not _entirely_
voluntarily, he did crypto during world war II and then they threatened
to draft him and put him on the ground in Korea if he didn't voluntarily
re-enlist for this new agency they were starting) and although he still
won't talk about most of what he did the one takeaway I did get is
nobody is really properly paranoid and I will never take any job that
requires any sort of security clearance because I refuse to get it on me.

But sure, tell me about crypto. Go for it.

> everything else is pretty non random.
> You are reading the same flash, executing the same code, with the same
> 1 core cpu, and without a high precision timer.

CPU cycle counter is a HPET. It's not a _good_ hpet, but the skew
between different timers in the system can provide jitter that can be
visible in the cycle counter. (It's not necessarily protected from other
users on the box, but if you've got other users on the box executing
arbitrary code on a _router_, you're doing it wrong.)

> Crypto 101 is "don't roll your own crypto", the code you are
> suggesting will make you feel safe when in reality it will change
> almost nothing

Yes, and that attitude is why heartbleed happened. Because
non-cryptographers never reviewed that code for over a decade and it
filled up with badly implemented crap.

We are not proposing rolling our own crypto algorithms, we are proposing
staying with the tried and tested APIs to the existing kernel crypto
algorithms until such a time as someone convincingly argues that a new
way of doing things is a significant improvement. Which you have not yet
done.

> Please also reread Bastian Bittorf, in his experience on 100 identical
> routers you have at least 2 identical ssh-key !

Which is why you mix in the mac address even though it's externally
visible. (The point of the hashing step is that mixing in known data
doesn't give you a known result as long as there's _some_ unknown data
in there. That at least makes the result unique and avoids collisions.)

Although on _top_ of that you really want to see a unique random block
on each machine (which is a manufacturing issue), and if you can't do
that then you can't give the machine a unique ssh host key either (yes
I've dealt with this manufacturing issue at more than one company).

AND if you have _any_ persistent storage you can save previous entropy
and feed it back in on next boot (keeping in mind that routers are
_never_ shut down properly and you don't want them to be brickable, but
you can reserve a small SD card partition or similar to update once the
entropy pool reports full and then daily after that. _IF_ this issue is
considered important enough, which depends on how much input engineers
have into the design vs management and marketing and legal.)

That said, the fundamental problem of routers having limited entropy
sources is not going to be solved by ANY software. Your function call
api and /dev/random have the exact same problem there so it's a red
herring. Initializing the pool from locally unique sources and
preserving accumulated entropy across reboots are mitigation strategies,
not solutions to the fundamental problem.

This is why so many web servers had sound cards in a PCI slot a decade
ago, not hooked up to anything but just feeding the low bits into the
entropy pool constantly. (Of course others argued that what they were
picking up was noise from inside the case and thus predictable if you
have the right machine specs, mathematicians, physicisits, and
supercomputers. Which the NSA probably does, but it would be way easier
for them to just go in and badusb the crash cart at the hosting facility.)

People add hardware random generators to all sorts of processors these
days, but of course who trusts Intel's RNG not to be backdoored by the NSA?

> You haven't answered my question, should i change the applet name to
> bbgetrandom ?

You haven't answered OUR question: what is the point of your new applet?

$RANDOM is built into the shell that's calling your applet. If your
applet is not called from the shell, it's probably called from a C
program, meaning you can call this new function yourself and shelling
out to a busybox applet to produce a random number from that context is
INSANE.

What is your use case? Why are you bothering to do this?

It's entirely possible your new approach is superior, but you have not
successfully articulated _why_ yet. Would you like to try again?

Rob


More information about the busybox mailing list