Re: [PATCH RFC v4 1/1] random: WARN on large getrandom() waits and introduce getrandom2()

From: Linus Torvalds
Date: Thu Sep 19 2019 - 11:50:38 EST


On Thu, Sep 19, 2019 at 8:20 AM Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> The silly "reset crng_init_cnt" does absolutely nothing to help that,
> but in fact what it does is to basically give the attacker a way to
> get an infinite stream of data without any reseeding (because that
> only happens after crng_read()), and able to extend that "block at
> boot" time indefinitely while doing so.

.. btw, instead of bad workarounds for a theoretical attack, here's
something that should add actual *practical* real value: use the time
of day (whether from an RTC device, or from ntp) to add noise to the
random pool.

If you let attackers in before you've set the clock on the device,
you're doing something seriously wrong.

And while this doesn't add much "serious" entropy, it does mean that
the whole "let's look for identical state" which is a _real_ attack,
goes out the window.

In other words, this is about real security, not academic papers.

Of course, attackers can still see possible bad random values from
before the clock was set (possibly from things like TCP sequence
numbers etc, orfrom that AT_RANDOM of a very early process, which was
part of the Android the attack). But doing things like delaying
reseeding sure isn't helping, which is what the crng_count reset does.

Linus
kernel/time/timekeeping.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index ca69290bee2a..67e74f7f4198 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -22,6 +22,7 @@
#include <linux/pvclock_gtod.h>
#include <linux/compiler.h>
#include <linux/audit.h>
+#include <linux/random.h>

#include "tick-internal.h"
#include "ntp_internal.h"
@@ -1256,6 +1257,7 @@ int do_settimeofday64(const struct timespec64 *ts)

/* signal hrtimers about time change */
clock_was_set();
+ add_device_randomness(ts, sizeof(*ts));

if (!ret)
audit_tk_injoffset(ts_delta);
@@ -1304,6 +1306,7 @@ static int timekeeping_inject_offset(const struct timespec64 *ts)

/* signal hrtimers about time change */
clock_was_set();
+ add_device_randomness(ts, sizeof(*ts));

return ret;
}