You are viewing bramcohen

Thu, Jul. 9th, 2009, 03:24 pm
Someone at Mozilla Foundation needs to be fired

Somebody at Mozilla decided they need lots of 'true' random numbers.

My patience for this subject completely ran out about five years ago, so this post is going to show a complete lack of diplomacy. I would like to emphasize, in advance, that this is my honest, reasoned opinion, not said in anger, and that if you ask my opinion again in the future I'll say the exact same thing.

Once a computer has collected a small number of 'true' random bits (maybe it's 128, maybe it's 256, but regardless it's small) there's no need whatsoever for it to block on collecting more 'random' numbers. A pseudorandom number generator based on AES will be able to generate random numbers based on that seed until the end of the universe and noone constrained by the laws of physics and math will ever be able to tell the difference between that and 'true' random numbers. This is extremely well established cryptography. To require 'true' random numbers is, to use an apt analogy, wankery. It does not, and cannot, do anything to improve security, and it mostly just causes huge amounts of pain. It is (and I repeat myself, because I have a hunch people will think I'm glossing over some nuance here) of no benefit whatsoever.

My advice to the Mozilla foundation (and again, this is my reasoned opinion, not said in anger, and I won't be changing my mind later): find out who was responsible for this policy of requiring lots of 'true' random numbers, and fire them. Fire them today. They have demonstrated gross incompetence, a total lack of understanding of the very most basic concepts in security.

Some people might think that if I knew more about who was behind this and what their specific motivations are, then that might change my mind. That is incorrect. The security field is filled with people who to non-experts seem very impressive and knowledgeable, especially when they're advocating, and even moreso demanding, very painful and difficult things in the name of security. Most of these people are frauds. I have had it with paying homage to the concept of impartiality when discussing these peoples's opinions. If someone spouts a bunch of technical mumbo-jumbo to bring the conversation to a place which a lay person has trouble understanding, then they may be able to make the argument be based on pure rhetoric, but gross incompetence is still gross incompetence, and despite having found an effective way to bullshit their way through, they're still wrong.

Thu, Jul. 9th, 2009 10:55 pm (UTC)
ciphergoth

Agreed entirely; this business drives me crazy!

(edit: though I don't think I'd advocate firing anyone!)

Edited at 2009-07-10 07:33 am (UTC)

Sat, Jul. 11th, 2009 03:23 am (UTC)
bramcohen

In my experience, it's best to fire people early and often

Thu, Jul. 9th, 2009 11:12 pm (UTC)
4zumanga

Even worse, as if there needed to be anything worse, the way they gather these "other strong random numbers" is by reading through temporary directories, including those which contain cached web pages, which are trivial to poison, within reason, with as much data as you like.

Certainly this person should be fired, and anyone involved in allowing this code to be submitted should have their commit privileges revoked.

Fri, Jul. 10th, 2009 02:50 am (UTC)
bramcohen

Best practices for maintaining a random number pool are an interesting subject, and way beyond the scope of what I wanted to cover here. The short of it is that it can be done right, and the attacks you mention can be stopped without having to carefully vet the data being mixed in, but I have little confidence that there weren't other idiocies in this release, given the big central obvious one.

Thu, Jul. 9th, 2009 11:13 pm (UTC)
codetoad

There's no evidence, based on that linked to blog, that they didn't understand what you're saying. A stupid implementation, for sure. But I'm guessing that:

1) Each new window is kinda like a new process, or something. So FF restarts all the security machinery, including random number generation.

2) They may have just been adding everything together to get one random number seed.

Fri, Jul. 10th, 2009 12:56 am (UTC)
robbat2

Hey, it's at least better than the Netscape RNG attack from 1995.
Parts of that are still evident in the NSS codebase.

In one addendum to the above, just remember to reseed your generator occasionally, or use separate generators for different sites. I think seeding them from the master generator should be safe as long as your generator is not purely iterative on the seed and mixes it in properly.

That is, given generator G with seed x, the following should not return related series:
G(G(x)[0]) = ...
G(G(x)[1]) = ...

Fri, Jul. 10th, 2009 02:32 am (UTC)
oddments

Reseeding for the same sort of 'best practices' reasons that motivate switching encryption keys periodically, so that capturing state once doesn't permanently compromise the RNG?

I notice that the Firefox design described seems to be built on the assumption that any RNG state saved between sessions is readily compromised, while the state during operation and the disposition of the temp files are not.

Fri, Jul. 10th, 2009 02:53 am (UTC)
bramcohen

If you'll read carefully, you'll see that I didn't say blocking should never happen, just that it shouldn't happen after some threshold of amount of entropy has been pulled into the pool.

Fri, Jul. 10th, 2009 08:11 am (UTC)
oddments

I saw that, and you offered this constraint as an alternative to a startup delay. The two ways to solve the described problem based on that constraint are by storing state between subsequent startups (so that the delay occurs only at install time), or by reducing the amount of entropy gathered at startup, which presupposes the NSS designers gathered way too much.

There are two other ways I can see that the NSS design might have ended up being too slow, though: gathering entropy from a source with a potentially very slow response, and gathering it from a source that's potentially not very random. If they're relying on reading everything in temporary file caches, it's possible they're encountering all three issues at once.

Fri, Jul. 10th, 2009 03:11 pm (UTC)
bramcohen

If a source isn't able to provide 256 random bits reasonably quickly, it probably isn't worth using as a source at all.

Fri, Jul. 10th, 2009 04:59 am (UTC)
robbat2

Here I'm in agreement with Bram (and the original code). The RNG state should never be saved to disk.

Reseeding either from raw entropy, or from a master PRNG as I described is simply to help mitigate some state capture attacks yes.

Most concerning are attacks where the PRNG is shared between all tabs/windows, and an attacker in one could predict the PRNG data used for other windows (assuming a predicable PRNG, which has happened before).

Fri, Jul. 10th, 2009 07:31 am (UTC)
oddments

By 'predictable PRNG' you mean one whose state can be guessed from access to the pseudorandom number stream, rather than requiring access to internal PRNG state information? I know simple PRNGs have been attacked this way, but I thought Bram's point was that this sort of predictability could be reliably avoided with known CSPRNG designs.

Fri, Jul. 10th, 2009 03:36 pm (UTC)
robbat2

In my other comment, I noted that if a master PRNG was being used to seed other PRNGs, then specific properties were required - I've seen cases where they failed to heed that requirement, and thus could be attacked by simply having an earlier copy of the PRNG that you iterated to gain the data that would be used later, and then replay it. In doing so, you don't need any internal state, just capturing the data further from another instance before it's used in the target PRNG.

Fri, Jul. 10th, 2009 02:57 am (UTC)
bramcohen

Best practices for random number generation are beyond the scope of this post - my point is that the current NSS implementation is most definitely not best practices, not even conservative behavior. It's just stupid.

Sun, Aug. 2nd, 2009 04:38 pm (UTC)
trs80 [typekey.com]

Yeah, the log for the file shows the "get entropy from system files" algorithm has been there since before 2001, when the file was moved to its current location: http://bonsai.mozilla.org/cvslog.cgi?file=mozilla/security/nss/lib/freebl/win_rand.c I suspect it only got shit when wtc@google.com changed it to recurse into directories in revision 1.18. NSS is just awful code though - it expects to be initialised once per application, which makes it useless for libraries.

Sun, Aug. 2nd, 2009 04:49 pm (UTC)
trs80 [typekey.com]

Reading the linked bug shows that the recurse directories code was originally for WindowsCE where entropy was at a premium, and it was then generalised to all Windows versions. Presumably WinCE devices have flash so scanning directories is cheap, which is not the case for hard drives in PCs. Anyway, if you're still looking for someone to blame, Brad Lassey is a Mozilla employee who works on Fennec, the browser for WinCE, who wrote the patch and obviously has no security experience, but was just trying to fix the bug on his platform, but neglected to test on others.

Fri, Jul. 10th, 2009 01:46 am (UTC)
hoserhead: NSS employment

Nobody at the Mozilla Foundation works on NSS. Nobody at the Mozilla Corporation works on NSS, either. For that, you can blame/praise Red Hat and Sun employees.

Fri, Jul. 10th, 2009 04:33 am (UTC)
illiterat: Re: NSS employment

I find it hard to believe that NSS itself is trawling the filesystem, so I'd assume that this is coming from some mozilla code which is just calling a "seed PRNG" NSS API.


Fri, Jul. 10th, 2009 05:29 am (UTC)
robbat2: Re: NSS employment

It DOES seem to be NSS :-(
nss-3.12.3/mozilla/security/nss/lib/freebl/win_rand.c:
There's void RNG_SystemInfoForRNG(void):
352 // now let's do some files
353 ReadSystemFiles();
Which goes to EnumSystemFiles, which has this gem:

181 static BOOL
182 EnumSystemFiles(Handler func)
183 {
184 PRUnichar szSysDir[_MAX_PATH];
185 static const int folders[] = {
186 CSIDL_BITBUCKET,
187 CSIDL_RECENT,
188 #ifndef WINCE
189 CSIDL_INTERNET_CACHE,
190 CSIDL_COMPUTERSNEARME,
191 CSIDL_HISTORY,
192 #endif
193 0
194 };

which comes from some windows header, possibly shlobj.h if the comments amongst the headers are correct.

The RNG_SystemInfoForRNG function itself is very interesting in what they take entropy from. Bad sources in my opinion.

Fri, Jul. 10th, 2009 09:56 am (UTC)
sysprv: Re: NSS employment

Can't find anything about RedHat or Sun on the informal history here: http://www.mozilla.org/projects/security/pki/nss/history.html

Or were you thinking of glibc's nss?

Fri, Jul. 10th, 2009 05:52 pm (UTC)
hoserhead: Re: NSS employment

Nope - NSS, the library used by Mozilla for security, has no Mozilla employees among its regular developers.

Fri, Jul. 10th, 2009 04:24 pm (UTC)
darth_spacey

I once worked somewhere where they considered all manner of schemes, including hooking into online traffic cameras, or into some kind of sideways-engineered smoke detector, as entropy generators for their crypto. What's more random than radioactive particle decay, right?

They ended up just leaving the systems as they were, and accepted that they'd run out of entropy once in a while.

Fri, Jul. 10th, 2009 07:20 pm (UTC)
allonymist

My advice to the Mozilla foundation (and again, this is my reasoned opinion, not said in anger, and I won't be changing my mind later): find out who was responsible for this policy of requiring lots of 'true' random numbers, and fire them

My reading on this -- based only on the blog post -- is that "needing lots of 'true' random numbers" is not the real motivation for NSS's stupid behavior. I agree that you only need a few hundred bits of entropy (tops) to keep your PRNG happy. But somebody who throws megabytes of data into their PRNG is not necessarily under the misapprehension that the PRNG needs megabytes of entropy. Instead, they may simply believe that the megabytes of data are not very random (and cache contents aren't!) and may be hoping that somewhere in there are the few hundred bits of entropy they need.

In other words, there isn't necessarily a fundamental misunderstanding of entropy and randomness here: all there is, is just a really really bad choice of entropy source.

IOW 2: seeding your PRNG with 10 megabytes from /dev/random is deeply idiotic -- but seeding it with 10 megabytes from /tmp is merely broken and stupid. ;)