Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Dec 2020 18:52:03 -0800
From:      Conrad Meyer <cem@freebsd.org>
To:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Subject:   Re: arc4random initialization
Message-ID:  <CAG6CVpVUPzaGK-CdqdvGEmytmkAH%2BQTrX0BRho-HPUts60HZpQ@mail.gmail.com>
In-Reply-To: <EB47F35A-EAD8-4B97-B676-FD8C5AD57398@FreeBSD.org>
References:  <20201206153625.13e349a8@bigus.dream-tech.com> <EB47F35A-EAD8-4B97-B676-FD8C5AD57398@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Dec 7, 2020 at 12:37 AM Mark Murray <markm@freebsd.org> wrote:
>
> Hi
>
> > On 6 Dec 2020, at 23:36, Dave Hayes <dave@jetcafe.org> wrote:
> >
> > So security-wise, just how bad is it to be improperly seeded? If I cann=
ot get
> > a valid entropy stash at boot time, can I delay the need for it until I=
 can get
> > a writable filesystem up and running?
> >
> > Thanks in advance for any cogent replies.
>
> This means that the random(4) device and relevant infrastructure like
> arc4random starts up in an insecure state and is not to be trusted for e.=
g.
> generating SSH keys.
>
> After you have used the machine for a while (exactly how long "depends"),
> it will reseed itself and become secure.
>
> Essentially, expect every boot off a DVD on the same hardware to reuse
> cryptographic keys and therefore be insecure.
>
> Once you've installed on some R/W medium and rebooted, the necessary
> entropy will have been stashed for you, and the first SSH keys will be
> generated properly.

+1 to what Mark wrote.

To add a little bit more, in CURRENT we have some sysctls around
initial seeding: the kern.random.initial_seeding subtree.  There are
four keys there:

Admin-configured (configuration):
kern.random.initial_seeding.bypass_before_seeding: if disabled we will
potentially deadlock boot rather than provide bad random data to
kernel consumers and user applications.  If enabled, we will provide
bad entropy if we're unseeded.
kern.random.initial_seeding.disable_bypass_warnings: if enabled, we
log messages when the former situation occurred.

Read-only knobs that reflect random safety during the boot process (diagnos=
tic):
kern.random.initial_seeding.arc4random_bypassed_before_seeding:
kern.random.initial_seeding.read_random_bypassed_before_seeding: If
these are non-zero, it means the corresponding operation
(arc4random(9), read_random(9)) was accessed when random(4) was
unseeded.  If these knobs are both zero, you know that all randomness
used during boot was high-quality (seeded).

To comment on some various other ideas / questions raised in the
thread (Hal, Dave):

> If I do a fresh install, when does the host's SSH key get generated and w=
here does the entropy for that step come from?

The system /etc/rc.d/sshd script generates SSH host keys if they
aren't present already.  So that's well into multiuser, by which time
the system random device is usually well-seeded, even on extremely
limited platforms.  An installer might also write those host keys,
although I'm not aware of one that does so.

> I assume lots of entropy is generated during the install.  Does that get =
written to the new system's disk so it has some at first boot?

bsdinstall has a script which does so from the runtime environment of
the installer, which is probably well-seeded:
usr.sbin/bsdinstall/scripts/entropy.  Other installers may or may not
write the unique entropy file; I'm not familiar with all installers.
Ideally they would all do something like what bsdinstall is doing for
entropy.

> Does the on-disk entropy file get updated occasionally (as compared to on=
ly at shutdown) so it doesn't get reused if the system crashes?

Yes.  cron runs libexec/save-entropy/save-entropy.sh periodically.
Unfortunately, this entropy location (/var/db/entropy) is only
available after userspace has started (/etc/rc.d/random) =E2=80=94 it is no=
t
used to seed the kernel during the early boot process.  Only
bootloader entropy is loaded very early on (/boot/entropy), and that
location is only saved on clean shutdown (/etc/rc.d/random).

> If so, how often is "occasionally"?  Will that turn into a wear-out probl=
em if running on a flash drive? (eg Raspberry Pi)

usr.sbin/cron/cron/crontab: once every 11 minutes, by default.  The
save-entropy default is 4kB, and each save is a new file (so you're
probably doing a directory entry write, an inode write, as well as a
data block write).  So call it 12kB/11min, or about 1.5 MB/day.

> Is there any indication as to when it has safely reseeded?

For the core random device, the message "random: unblocking device."
is printed in dmesg and logged to /var/log/messages.

RW wrote:

> The risk would be that kernel arc4random is initialized early and insecur=
ely and there's no appropriate read_random() call to reseed it before somet=
hing critical uses it.

arc4random(9) is integrated with random(4), so that arc4random is
immediately reseeded when the random device is seeded.  This logic can
be found in libkern/arc4random.c and dev/random/randomdev.c; look for
the variable 'arc4rand_iniseed_state' and the 'ARC4_ENTR_HAVE'
constant.  However, the concern still applies to userspace
arc4random(3), which is not integrated with core random(4) reseeds.

(And in CURRENT, the FXRNG random(4) mode *does* integrate userspace
arc4random(3) with random(4) reseeds, but that code isn't yet enabled
in GENERIC kernels.)

> IMO it would be better to eliminate that 0.7s period by getting enough en=
tropy from the hardware generator instantaneously when Fortuna initializes.=
 Whatever the paranoia over these generators they're better than no seeding=
 at all.

Totally agree.  We actually do this on CURRENT if
kern.random.initial_seeding.bypass_before_seeding=3D0 and a fast random
source (e.g., RDRAND) is available.  Look for
randomdev_wait_until_seeded() (both function body and callers) in
sys/dev/random/randomdev.c.

Hope that helps,
Conrad



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG6CVpVUPzaGK-CdqdvGEmytmkAH%2BQTrX0BRho-HPUts60HZpQ>