On 08/22/2012 11:43, David E. O'Brien wrote:> Author: obrien > Date: Wed Aug 22 18:43:21 2012 > New Revision: 239569 > URL: http://svn.freebsd.org/changeset/base/239569 > > Log: > Remove old entropy seeding after consumption initializing /dev/random PRNG. > Not doing so opens us up to replay attacks.I object to this change, and would like to see it discussed more. When I did the original implementation of the entropy seeding scripts this issue was discussed, and the decision not to remove the entropy after seeding was deliberate. There are 3 possibilities. First, the system boots normally, gets seeded, and runs for a period of time longer than ($entropy_save_num x cron interval), which by default is 88 minutes. In this case all of the entropy files will be replaced, so the "postrandom" change will be spurious. In the second case, the system boots successfully, gets seeded, but runs for less than the default 88 minutes. In that case there will be at least (uptime / cron interval) new files, and the same number of old files removed. So while some of the entropy will be "stale" at next reboot, it won't all be the same, so even the stale entropy is better than nothing in helping to reseed. In the third case, the system boots, but is then rebooted again before the cron interval has had a chance to replace even 1 file. This is the case where removing the old entropy is particularly pathological. It reduces the available seeding material without adding anything new. From a security perspective, that's worse than the possibility of a replay attack. For all 3 cases, it's important to keep in mind a few things. Primarily, yarrow is designed to avoid exactly the kind of "replay" problem that this change was intended to fix, so it's almost certainly at best unnecessary. Of nearly equal importance it should be kept in mind that we add a non-zero amount of unique material at every boot, so a true replay attack isn't possible, even without this change. In short, this change is at best unnecessary, and possibly detrimental. I'd like to see the postrandom script backed out, but I'll leave it open for others to comment. On a less serious note:> Modified: head/etc/rc.d/random > =============================================================================> --- head/etc/rc.d/random Wed Aug 22 18:35:17 2012 (r239568) > +++ head/etc/rc.d/random Wed Aug 22 18:43:21 2012 (r239569) > @@ -4,7 +4,7 @@ > # > > # PROVIDE: random > -# REQUIRE: var initrandom > +# REQUIRE: initrandom varThis change is spurious, rcorder(8) doesn't care what order they come in.> # BEFORE: netif > # KEYWORD: nojail shutdown > > @@ -14,6 +14,9 @@ name="random" > start_cmd="random_start" > stop_cmd="random_stop" > > +extra_commands="saveseed" > +saveseed_cmd="${name}_stop"I don't understand the need for this. Doug -- I am only one, but I am one. I cannot do everything, but I can do something. And I will not let what I cannot do interfere with what I can do. -- Edward Everett Hale, (1822 - 1909)
On Sun, 02 Sep 2012 15:20:31 -0700 Doug Barton wrote:> On 08/22/2012 11:43, David E. O'Brien wrote: > > Author: obrien > > Date: Wed Aug 22 18:43:21 2012 > > New Revision: 239569 > > URL: http://svn.freebsd.org/changeset/base/239569 > > > > Log: > > Remove old entropy seeding after consumption > > initializing /dev/random PRNG. Not doing so opens us up to replay > > attacks. > > I object to this change, and would like to see it discussed more.No entropy file is effectively equivalent to a known file and anything is better than that. Simply writing out a new version of /entropy would be better. The more significant problem is that initrandom dumps some very low-grade entropy into /dev/random before the entropy file (see below). Since /dev/random has very limited buffering, and processes the buffers in a timed loop, it's almost certain that the first entropy file is completely discarded. IMO the order should be reversed or the low-grade stuff should be piped through sha256. # XXX temporary until we can improve the entropy # harvesting rate. # Entropy below is not great, but better than nothing. # This unblocks the generator at startup ( ps -fauxww; sysctl -a; date; df -ib; dmesg; ps -fauxww ) \ | dd of=/dev/random bs=8k 2>/dev/null cat /bin/ls | dd of=/dev/random bs=8k 2>/dev/null # First pass at reseeding /dev/random. # case ${entropy_file} in [Nn][Oo] | '') ;; *) if [ -w /dev/random ]; then feed_dev_random "${entropy_file}" fi ;; esac
Doug, On Sun, Sep 02, 2012 at 03:20:31PM -0700, Doug Barton wrote:> In the third case, the system boots, but is then rebooted again before > the cron interval has had a chance to replace even 1 file. This is the > case where removing the old entropy is particularly pathological. ItI believe you're missing the point that we don't just cleanup old entropy file -- we re-generate it via "/etc/rc.d/random fastsaveseed" call in postrandom_start()> > +extra_commands="saveseed" > > +saveseed_cmd="${name}_stop" > > I don't understand the need for this.That's how "/etc/rc.d/random fastsaveseed" translates in to "/etc/rc.d/random stop", which does the jobs of re-generating seed file. In the end, assuming machine boots up passed postrandom script, we're left with no stale seed files, but a freshly generated ${entropy_file_confirmed}, which should be sufficient to seed next bootup. Thanks
(shameless thread hijacking) Speaking of rc.d and entropy, is the following code in /etc/rc.d/sshd really necessary? seeded=`sysctl -n kern.random.sys.seeded 2>/dev/null` if [ "x${seeded}" != "x" ] && [ ${seeded} -eq 0 ] ; then warn "Setting entropy source to blocking mode." echo "====================================================" echo "Type a full screenful of random junk to unblock" echo "it and remember to finish with <enter>. This will" echo "timeout in ${timeout} seconds, but waiting for" echo "the timeout without typing junk may make the" echo "entropy source deliver predictable output." echo "" echo "Just hit <enter> for fast+insecure startup." echo "====================================================" sysctl kern.random.sys.seeded=0 2>/dev/null read -t ${timeout} junk echo "${junk}" `sysctl -a` `date` > /dev/random fi Considering, among other factors, how late in the boot sshd actually starts, and how much disk and / or network activity has occurred by that point. I don't believe this was how it was initially supposed to work, by the way. The original code *intentionally* always blocked, but it was slightly obfuscated. Two years after it was written, someone who misunderstood it submitted a PR, and several other someones who didn't understand it either came up with an incorrect fix and committed it. Neither Mark, who wrote the original code, nor I, who was (and still am) the OpenSSH maintainer, were consulted. BTW, it might be a good idea to run "/etc/rc.d/sshd keygen" from the installer if sshd is enabled during installation. DES -- Dag-Erling Sm?rgrav - des@des.no
On Sun, Sep 02, 2012 at 03:20:31PM -0700, Doug Barton wrote:> On 08/22/2012 11:43, David E. O'Brien wrote: > > Author: obrien > > Date: Wed Aug 22 18:43:21 2012 > > New Revision: 239569 > > URL: http://svn.freebsd.org/changeset/base/239569 > > > > Log: > > Remove old entropy seeding after consumption initializing /dev/random PRNG. > > Not doing so opens us up to replay attacks. > > I object to this change, and would like to see it discussed more. > > When I did the original implementation of the entropy seeding scripts > this issue was discussed, and the decision not to remove the entropy > after seeding was deliberate.Hi Doug, I would like to refresh my memory of this discussion. Can you help me narrow down the date and mailing list such that I can go find it archives? It may help me understand your POV in this thread. I've read what I could find from Bruce Schneier on entropy seeding. It is my read that to not delete the seed input goes squarely against the yarrow inventor's recommendations. I tried to document this in the commit. Do you have access to Practical Cryptography, ISBN: 0-471-22357-3 by Niels Ferguson and Bruce Schneier that you could read 10.5 and 10.6 and give your thoughts?> There are 3 possibilities. First, the > system boots normally, gets seeded, and runs for a period of time longer > than ($entropy_save_cum x cron interval), which by default is 88 > minutes. In this case all of the entropy files will be replaced, so the > "postrandom" change will be spurious.I almost agree, but not quite. My read of /usr/libexec/save-entropy is that it does not overwrite ${entropy_file}. Only that /usr/libexec/save-entropy saves additional seeding material. Thus there is still a chance of replaying (reseeding with) ${entropy_file}. I'm curious, where did the default value of ${entropy_save_num} of "8" come from? Given we're talking about real machines and thus finite constraints in space, why stuff in 8 * 2k worth of seed all at the same time? What is the improvement in the pseudo randomness in /dev/random output after that much seeding? Why not 1/2 that value (4)? Or why not 9, to maximize the amount of seeding within a single digit extension?> In the second case, the system boots successfully, gets seeded, but runs > for less than the default 88 minutes. In that case there will be at > least (uptime / cron interval) new files, and the same number of old > files removed. So while some of the entropy will be "stale" at next > reboot, it won't all be the same, so even the stale entropy is better > than nothing in helping to reseed.It seems this is a point of contention. Arthur and I disagree. I believe you do not feel seeding with (uptime / cron interval) new [/dev/random generated] files is sufficient for a good pseudo random /dev/random. Is that correct? I believe you are questioning what is enough entropy seeding for obtaining a secure key? And that it entropy_save_num(=8) is required or strongly recommended. This is such a key question that Schneier even states this is probably the hardest problem to solve in PRNG design. The yarrow design has mechanisms it uses to answer this. It tracks the number of bits of entropy fed into it to decide for itself.> In the third case, the system boots, but is then rebooted again before > the cron interval has had a chance to replace even 1 file. This is the > case where removing the old entropy is particularly pathological. It > reduces the available seeding material without adding anything new. From > a security perspective, that's worse than the possibility of a replay > attack.How is it worse? /etc/rc.d/postrandom does add something new by generating a new ${entropy_file} during this time -- providing for 4k of good entropy seed. Less assume only a 10% entropy rate. That's still 409 bits of entropy -- which I claim is good enough to prime yarrow to operate securely.> For all 3 cases, it's important to keep in mind a few things. Primarily, > yarrow is designed to avoid exactly the kind of "replay" problem that > this change was intended to fix, so it's almost certainly at best > unnecessary.I am not sure what section of http://www.schneier.com/paper-yarrow.ps.gz are you referring to. I do not see "replay" explicitly stated. Please note that section 3.1 "How PRNGs are Compromised" in the paragraph titled "Mishandling of Keys and Seed Files" Schneier states: seed files are easy to mishandle in various ways, ..., or by opening a seed file, but failing to update it every time it is used. That statement is in agreement with everything else I've seen from Schneier on this subject. Also section 5.2 "Entropy Accumulator" in the "Security Arguments" paragraph: Consider the situation of an attacker trying to predict the whole sequence of inputs to be fed into the user's entropy accumulator. ... Ultimately, an attacker in this position cannot be resisted effectively by the design of the algorithm, ...> Of nearly equal importance it should be kept in mind that > we add a non-zero amount of unique material at every boot, so a true > replay attack isn't possible, even without this change.What is the non-zero amount of unique material we seed at every boot? Most of the 'better_than_nothing' output is guessable by a local non-root account. The best thing saving us when the seed inputs are known, is the stirring in of the CPU cycle counter.> In short, this change is at best unnecessary, and possibly detrimental.I do not see how it is either of those. Please explain further. -- -- David (obrien@FreeBSD.org) Obligatory amusement: http://www.chmil.org/bruce-facts-all.txt It was based on the Schneier Axiom, which reads: "Bruce Schneier said so."