On 8/15/13 11:51 PM, Patrick Pelletier wrote:
On Aug 15, 2013, at 10:38 PM, Nico Williams wrote:
Hmm, I've only read the article linked from there:
http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html
Yeah, that's the only place I've seen it, and then the Google+ thread I
linked to is essentially the comment area for that post. We (meaning
those of us commenting in the thread) haven't gotten any official answer
from Google, but Nikolay Elenkov has been very helpful in reconstructing
what seems to be happening. We've exchanged a few more posts this
evening, and it appears that what's happening is that OpenSSL is
correctly self-seeding when system_server starts, but then system_server
forks (without execing) to start multiple processes, and these processes
are producing the same random sequence. It's not yet entirely clear
why, since the OpenSSL source code looks like it's trying to be
fork-safe, but it appears that somehow in practice it's not succeeding.
s/system_server/zygote/
So, it appears that the problem is that since OpenSSL merely mixes in
the pid to the existing random state, once the pids wrap, you will have
had two processes that have generated the exact same random sequence,
since they started with the same state (before the fork) and mixed in
the same thing (the pid) after the fork, resulting in the same output.
(This is in contrast to the approach of comparing the old and new pids,
and doing a full reseed from /dev/urandom if they differ, which is what
is done by Nick Mathewson's preliminary but already excellent-looking
libottery.)
Nikolay Elenkov wrote a proof-of-concept that shows the pid-wrapping bug
on Android, and then I took it one step further and wrote a
proof-of-concept using OpenSSL in C, demonstrating that this is an
underlying OpenSSL bug:
https://gist.github.com/ppelleti/6290984
An easy way to work around this, if you don't mind linking against
pthreads, is to do this at the start of your application, after
initializing OpenSSL:
typedef void (*voidfunc) (void);
if (ENGINE_get_default_RAND () == NULL)
pthread_atfork (NULL, (voidfunc) RAND_poll, (voidfunc) RAND_poll);
But, of course, this ought to eventually be fixed in OpenSSL itself.
(By using the pid-comparison trick that libottery uses, rather than just
mixing in the pid.) I'm happy to submit a patch, if we think there's a
good chance it would be considered?
--Patrick
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org