
Google confirms Java and OpenSSL crypto PRNG on Android are broken - quadhome
http://android-developers.blogspot.com.au/2013/08/some-securerandom-thoughts.html
======
tptacek
Here again I will posit:

Secure programs should rely on /dev/urandom, to the exclusion of other
CSPRNGs, and should specifically eschew userland CSPRNG engines even when
they're seeded from /dev/urandom.

This Android bug is another in a line of bugs in userland CSPRNGs, the most
famous of which was Debian's OpenSSL CSPRNG bug which gave up everyone's SSH
key. CSPRNGs have bugs. When you rely on a userland CSPRNG, you're relying on
two single points of failure: the userland CSPRNG and the OS's CSPRNG.
Failures of _either_ aren't generally survivable.

There are people who are smarter than me (notably 'cperciva) who disagree with
me on this, but this is an idea I got from DJB's NACL design paper; it's not
my own crazy idea.

I got to eat dinner with Dan Bernstein the other day, by the way, and it turns
out NACL is pronounced "lasagna".

~~~
H3g3m0n
Except if /dev/urandom is using a hardware based random number generator, then
you have to trust that the hardware hasn't received some NSA alterations at
some point during the design.

The NSA did design a random number generator that likely had a backdoor in it:
[https://en.wikipedia.org/wiki/Dual_EC_DRBG#Controversy](https://en.wikipedia.org/wiki/Dual_EC_DRBG#Controversy)).

Here's Bruce Schneier talking about it:
[https://www.schneier.com/blog/archives/2007/12/dual_ec_drbg_...](https://www.schneier.com/blog/archives/2007/12/dual_ec_drbg_ad.html)

Also it's in Windows (although it's not used by default but userspace programs
could rely on it).
[https://www.schneier.com/blog/archives/2007/12/dual_ec_drbg_...](https://www.schneier.com/blog/archives/2007/12/dual_ec_drbg_ad.html)

It would be possible for the NSA to go to Intel and get them to put in
something in their random number generator that would let them to basically
break the encryption by massively reducing the keyspace if they have the
secret key.

~~~
patio11
If you don't trust the hardware, then you've already lost, no matter what
algorithmic construction you are using. How are you going to trust your random
number generator if 1 + 1 = 2 except when it equals NSA?

(This is one of those times where I regret HN that has twin interests in
software security as an engineering science and software security as a
political statement.)

~~~
H3g3m0n
> If you don't trust the hardware, then you've already lost, no matter what
> algorithmic construction you are using. How are you going to trust your
> random number generator if 1 + 1 = 2 except when it equals NSA?

You can verify the random number generator. If you know the algorithm and the
seed values you can run it on multiple different platforms, or with a pen and
paper and verify that the output is as expected and repeatable. If you have
large amounts of entropy you are feeding into it, you can log it for testing
purposes.

There are also apparently some EC based algorithms that can be used to fix or
at lease reduce the impact of a compromised random number generator.

That might not protect against a active attack on your specific system by the
NSA (they could send/embedded a magic packet that gives them total control
over the CPU for example), might even be possible for it to happen on the NIC
controller rather than the CPU if it has access to the system bus. At the
least they could flip it into some kind of backdoor random number mode by
embedding some extra data in a TLS handshake or whatever. But it should
protect against widespread passive surveillance.

~~~
tptacek
Reducing the impact of a CSPRNG state compromise is a basic design goal for
CSPRNGs, and you don't need ECC to do it; the "NSA backdoored" RNG you're
referring to is one that no system anyone knows about actually uses, for that
reason.

Again: you're making a point that has nothing to do with my comment. If you
don't trust RDRAND, don't use it. But you should still be using the OS's
CSPRNG. Just make sure your OS isn't using RDRAND. Done and done.

------
patio11
Since this is as good a time as any: I snidely implied that this was likely to
have been due to a bug on the part of the Bitcoin community rather than a
design error in the Android platform. That seemed like a reasonable guess at
the time, but it was wrong, so: sorry, Bitcoin et al devs.

~~~
glurgh
It was not a reasonable guess even at the time because it should have taken
you all of 2 minutes to verify it is, in fact, not a reasonable guess. I don't
think there is some great tragedy or mistake in being wrong about this but if
you're going to gracefully admit wrongness, admit to the right kind.

You were wrong then and you could have easily known you were wrong then. This
new disclosure doesn't make you righter or wronger in retrospect.

~~~
marshray
How would you verify this in 2 minutes?

~~~
glurgh
The programs in question were not manually seeding the RNG, as was patio11's
suggestion. The app implementors in this case don't seem to have actually done
anything wrong at all.

~~~
marshray
But it took us days to arrive at this conclusion.

~~~
j_s
I believe this is the point in the discussion where people willing to do some
digging indicated that the problem was most likely not in the apps:

[https://news.ycombinator.com/item?id=6195707](https://news.ycombinator.com/item?id=6195707)

It wasn't days, but I can't say for sure that it was minutes... my vote would
be for hours! :)

------
raverbashing
"Developers who use JCA for key generation, signing or random number
generation should update their applications to explicitly initialize the PRNG
with entropy from /dev/urandom or /dev/random."

Really? This is what's missing?

They build a whole infrastructure for crypto and forget to do _that_?

~~~
pjmlp
The Sun/Oracle JVM does it, as many other JVMs.

Just Dalvik does not.

------
dekz
> Some SecureRandom Thoughts

I feel like the author of the post isn't giving this the severity that it
deserves. The title makes it sound like a thought experiment, here is an
example where the original title is (let's face it) shit and the editorial
title here is relevant.

~~~
healsjnr1
Agreed. The whole thing is a bit blase.

Also, anyone else find it concerning that they advocate presenting
/dev/urandom as SHA1-PRNG when it isn't? I don't even see why they did this?
They could have wrapped the default SecureRandom and forced it to seed bytes
with /dev/urandom.

Also, why are they writing to /dev/urandom??

~~~
tptacek
Presumably because some Android devices don't boot cold with a lot of entropy,
so there's a virtue in helping kickstart it.

~~~
taspeotis
I'm a layperson when it comes to cryptography. Can you clarify how much
entropy a device would need to become cryptographically secure, and the
profile of an Android device that couldn't collect enough entropy quickly?
E.g. most devices could collect battery %, 3G radio noise levels, wifi noise,
readings from the capacitive touch sensors, accelerometer, microphone etc.,
yes?

~~~
marshray
> Can you clarify how much entropy a device would need to become
> cryptographically secure

200 bits.

------
conformal
needless to say, android passed its fips certification with flying colors.

just another secure mobile OS. nothing to see here, move along.

did i mention that you should never store anything of actual import on a
phone?

~~~
cbhl
At what point do you differentiate between a phone and a computer?

~~~
throwawaykf02
In this context: At the point where one begins to be much, much more likely to
be misplaced than the other.

------
ParadisoShlee
Let me get this straight. Somebody spent time to hunt down the original issue
with the RNG. Followed by the time required to exploit the issue. Then focused
on attacking bitcoin environment in some way. Taking a total of 55 bitcoins.

That seem's like a lot of work for $5000.... Some Blackhat burning 0day for
giggles?

It's also very impressive that the BT community caught them so quickly.

~~~
m0nastic
Part of the philosophical justification for the "full-disclosure movement" is
the belief that, much like scientific discoveries, they almost never happen in
a vacuum by a lone brilliant researcher.

Which is to say, that it is entirely possible (I'm not going to presuppose how
likely) that this has been known about for some time, and used for other
nefarious purposes in a manner that wasn't so "easily" detected (the existence
of a master record of all Bitcoin transactions makes it much more likely for
this to be found than people exploiting it in some random app).

It could be that somewhere right now, in dozens of coffee shops throughout
Eastern Europe, South America, and Asia, a group of collective hackers, each
unaware of the existence of any others, read this blog post and uttered their
linguistic equivalent of "Son of a Bitch".

~~~
e12e
You forgot the coffee shops in Langley, VA.

------
marshray
(cross post from other article)

I thought OpenSSL's default code already pulled from /dev/[u]random at
initialization?

~~~
rwg
The short answer is yes:

The first call to ssleay_rand_bytes() (which is what RAND_bytes() calls
eventually become with the default RAND_METH) will call RAND_poll(), which on
Unix-but-not-OpenBSD-or-VOS will try reading ENTROPY_NEEDED (32) bytes from
/dev/urandom, /dev/random, and /dev/srandom (in that order). Then, for grins,
it throws getpid(), getuid(), and time() into the pool.

The longer answer is maybe:

• RAND_poll() relies on a #define named DEVRANDOM to figure out where to go
looking for random devices. If DEVRANDOM is undefined, e_os.h will define it
to "/dev/urandom","/dev/random","/dev/srandom". If DEVRANDOM is defined but
empty, then the code in rand_unix.c's RAND_poll() ends up skipping seeding
from random devices entirely and only tosses getpid(), getuid(), and time()
into the pool.

• If something changes OpenSSL's default RAND_METH so it's not RAND_SSLeay(),
all bets are off.

Despite staring at all of the code between Android's SecureRandom.java and
their OpenSSL tree's crypto/rand directory for three hours, I can't figure out
how they screwed this up.

~~~
marshray
Complexity kills.

Thank you for staring at the code for three hours BTW. :-)

~~~
rwg
As an added fun bonus, it looks like the NativeCrypto Java wrapper around
OpenSSL wrongly assumes that RAND_bytes() returns 0 on failure and not-zero on
success. In reality, it returns 1 on success, 0 on failure, and -1 on super
ultra mega failure.

~~~
marshray
That evil API has bitten _so_ many projects.

------
MichaelMoser123
/dev/urandom is usually pseudo random, so as an initialization for SHA1PRNG
random number generator it is not good enough. It seems that the suggested fix
is not good enough; you need a real source of entropy - which is /dev/random.

The problem with /dev/random is that sometimes there is not enough system
entropy (depending on the available hardware sources), so reading from it can
block;

On smartphones they might use the radio signals as a source of entropy, get
some data from the radio then MD5 the stuff; couldn't they do just that ?

~~~
__alexs
/dev/urandom and /dev/random follow the same bit generation routine except
that /dev/random blocks when the estimated entropy in the input pool falls too
low.

The SoCs on phones often have HWRNG support, they just don't always use it, or
someone forgets to actually seed their entropy pool with it because they
assumed some other bit of code would, which seems to be what happened here.

------
general_failure
I don't understand. Isn't seeding very fundamental? How could they forget
this?

~~~
marshray
QC/QA is all about testing for repeatability. Testing for entropy means
proving a negative: that the initial parameters will never repeat across all
devices that will ever be booted. Entropy gathering is really really difficult
to test within a normal engineering process.

------
oggy
Am I reading the patch correctly in that Android versions below 4.1 are not
affected?

~~~
syjer
there are two fix: applyOpenSSLFix and installLinuxPRNGSecureRandom .

The first is only applied to jelly bean. The prng one is for all the versions.

