[jitsi-dev] OTR key generation concern


#1

Hi everyone!

After playing around with a Jabber account using OTR, the key generation
is *incredibly* fast and I'm concerned that there is not a proper
entropy source used for that explaining the speed here.

I've dig a bit in the code (FYI, I'm no Java expert) and found out that
bouncycastle library is used for the crypto "workload" and the key
generation uses the SecureRandom[1] class from Java as a PRNG.

https://github.com/jitsi/otr4j/blob/master/src/main/java/net/java/otr4j/crypto/OtrCryptoEngineImpl.java#L63

Reading the documentation, you can seed it explicitely with a source of
entropy but none is used in otr4j basically meaning that Java will
handle it. I did some test aside with that class, on my Linux machine,
and /dev/random AND urandom are opened but only urandom is used as
entropy so my guess is that random might have blocked the application so
Java switched to the non blocking one.

However, for OTR key generation, strong entropy is crucial! especially
for OTR that uses DH parameters which needs a very strong entropy.

It seems to me that otr4j should acquire entropy from the strongest
source available on the OS (by default, on linux that would be
/dev/random) even though it blocks the application. Else, the Java
implementation decides what to use and that might leads to bad entropy
(especially considering Java history with security...).

Thoughts?

Cheers!
David

[1]
http://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html


#2

I haven't looked at the code, but if it is as you describe I do agree.
using /dev/random this can take minutes. I guess the wait time is
shorter for shorter keys, but it might still take several seconds.
For this reason it's important that the user is properly informed.
Maybe a message like: "A strong cryptographic key is being generated,
this may take a few seconds. You may speed up the process by moving
your mouse or taking some other actions."
Maybe Jitsi doesn't need to be blocked completely. Simple multi-threaded
programming is indeed simple in java, so the GUI could remain
responsive. Maybe there's something sensible to do in the meantime.

If it takes a minute or so the nicest solution in my opinion would be to
let the user play some mini-game to keep him busy and help with entropy
generation at the same time.

Regards,
Philipp

···

On Wed, 20 Nov 2013 12:59:03 -0500 David Goulet <dgoulet@ev0ke.net> wrote:

Hi everyone!

After playing around with a Jabber account using OTR, the key
generation is *incredibly* fast and I'm concerned that there is not a
proper entropy source used for that explaining the speed here.

I've dig a bit in the code (FYI, I'm no Java expert) and found out
that bouncycastle library is used for the crypto "workload" and the
key generation uses the SecureRandom[1] class from Java as a PRNG.

https://github.com/jitsi/otr4j/blob/master/src/main/java/net/java/otr4j/crypto/OtrCryptoEngineImpl.java#L63

Reading the documentation, you can seed it explicitely with a source
of entropy but none is used in otr4j basically meaning that Java will
handle it. I did some test aside with that class, on my Linux machine,
and /dev/random AND urandom are opened but only urandom is used as
entropy so my guess is that random might have blocked the application
so Java switched to the non blocking one.

However, for OTR key generation, strong entropy is crucial! especially
for OTR that uses DH parameters which needs a very strong entropy.

It seems to me that otr4j should acquire entropy from the strongest
source available on the OS (by default, on linux that would be
/dev/random) even though it blocks the application. Else, the Java
implementation decides what to use and that might leads to bad entropy
(especially considering Java history with security...).

Thoughts?

Cheers!
David

[1]
http://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html

From my experience GPG where I generated 4096 bit keys


#3

using /dev/urandom is the correct way (not /dev/random). /dev/urandom uses
a hash function to generate an endless stream of random numbers.

For the sake of crypto arguement /dev/urandom is 'as strong as /dev/random'
unless the underlying hash function has a serious weakness.

regards,

ralf

···

On Wed, Nov 20, 2013 at 5:59 PM, David Goulet <dgoulet@ev0ke.net> wrote:

Hi everyone!

After playing around with a Jabber account using OTR, the key generation
is *incredibly* fast and I'm concerned that there is not a proper
entropy source used for that explaining the speed here.

I've dig a bit in the code (FYI, I'm no Java expert) and found out that
bouncycastle library is used for the crypto "workload" and the key
generation uses the SecureRandom[1] class from Java as a PRNG.

https://github.com/jitsi/otr4j/blob/master/src/main/java/net/java/otr4j/crypto/OtrCryptoEngineImpl.java#L63

Reading the documentation, you can seed it explicitely with a source of
entropy but none is used in otr4j basically meaning that Java will
handle it. I did some test aside with that class, on my Linux machine,
and /dev/random AND urandom are opened but only urandom is used as
entropy so my guess is that random might have blocked the application so
Java switched to the non blocking one.

However, for OTR key generation, strong entropy is crucial! especially
for OTR that uses DH parameters which needs a very strong entropy.

It seems to me that otr4j should acquire entropy from the strongest
source available on the OS (by default, on linux that would be
/dev/random) even though it blocks the application. Else, the Java
implementation decides what to use and that might leads to bad entropy
(especially considering Java history with security...).

Thoughts?

Cheers!
David

[1]
http://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html

_______________________________________________
dev mailing list
dev@jitsi.org
Unsubscribe instructions and other list options:
http://lists.jitsi.org/mailman/listinfo/dev


#4

I can confirm that OTR key generation using Psi+ (on Linux), with Pidgin
(Windows, Linux) and with Adium (Mac) takes _significantly_ longer than
with Jitsi.
(using Psi+ with OTR on Ubuntu you have even the impression the the
machine "hangs" because the duration is quite long).
MS

PGP.sig (489 Bytes)

···

On 11/20/13 7:36 PM, Philipp Überbacher wrote:

* PGP Signed by an unknown key

On Wed, 20 Nov 2013 12:59:03 -0500 > David Goulet <dgoulet@ev0ke.net> wrote:

Hi everyone!

After playing around with a Jabber account using OTR, the key
generation is *incredibly* fast and I'm concerned that there is not a
proper entropy source used for that explaining the speed here.

I've dig a bit in the code (FYI, I'm no Java expert) and found out
that bouncycastle library is used for the crypto "workload" and the
key generation uses the SecureRandom[1] class from Java as a PRNG.

https://github.com/jitsi/otr4j/blob/master/src/main/java/net/java/otr4j/crypto/OtrCryptoEngineImpl.java#L63

Reading the documentation, you can seed it explicitely with a source
of entropy but none is used in otr4j basically meaning that Java will
handle it. I did some test aside with that class, on my Linux machine,
and /dev/random AND urandom are opened but only urandom is used as
entropy so my guess is that random might have blocked the application
so Java switched to the non blocking one.

However, for OTR key generation, strong entropy is crucial! especially
for OTR that uses DH parameters which needs a very strong entropy.

It seems to me that otr4j should acquire entropy from the strongest
source available on the OS (by default, on linux that would be
/dev/random) even though it blocks the application. Else, the Java
implementation decides what to use and that might leads to bad entropy
(especially considering Java history with security...).

Thoughts?

Cheers!
David

[1]
http://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html

I haven't looked at the code, but if it is as you describe I do agree.
From my experience GPG where I generated 4096 bit keys
using /dev/random this can take minutes. I guess the wait time is
shorter for shorter keys, but it might still take several seconds.
For this reason it's important that the user is properly informed.
Maybe a message like: "A strong cryptographic key is being generated,
this may take a few seconds. You may speed up the process by moving
your mouse or taking some other actions."
Maybe Jitsi doesn't need to be blocked completely. Simple multi-threaded
programming is indeed simple in java, so the GUI could remain
responsive. Maybe there's something sensible to do in the meantime.

If it takes a minute or so the nicest solution in my opinion would be to
let the user play some mini-game to keep him busy and help with entropy
generation at the same time.

Regards,
Philipp

* Unknown Key
* 0x3881DE95

_______________________________________________
dev mailing list
dev@jitsi.org
Unsubscribe instructions and other list options:
http://lists.jitsi.org/mailman/listinfo/dev


#5

We're gather samples from the audio device (I don't know about the
merits of that entropy source) at the start of the application in
order to seed a random generator used by ZRTP and SDES. We're not
using that for DTLS-SRTP. Now you're talking about OTR. I guess we'd
better introduce an OSGi service in libjitsi and use that everywhere?


#6

I was thinking the same thing.

It's good that lack of latency was enough to get this thread started
but that's not a feature after all, so we'd better avoid it.

···

On Wed, Nov 20, 2013 at 8:20 PM, Lyubomir Marinov <lyubomir.marinov@jitsi.org> wrote:

We're gather samples from the audio device (I don't know about the
merits of that entropy source) at the start of the application in
order to seed a random generator used by ZRTP and SDES. We're not
using that for DTLS-SRTP. Now you're talking about OTR. I guess we'd
better introduce an OSGi service in libjitsi and use that everywhere?

_______________________________________________
dev mailing list
dev@jitsi.org
Unsubscribe instructions and other list options:
http://lists.jitsi.org/mailman/listinfo/dev

--
Emil Ivov, Ph.D. 67000 Strasbourg,
Project Lead France
Jitsi
emcho@jitsi.org PHONE: +33.1.77.62.43.30
https://jitsi.org FAX: +33.1.77.62.47.31


#7

I assume you mean samples from the microphone?
I'm far from an expert, but one possible problem is obvious: What if
the microphone is disabled when jitsi is started? Nothing but Zeros.
Chances are that I use this zero-seed, so I have to throw away my
jitsi config again.

I'm not sure how random the result is in the case of the enabled
microphone, but my guess is that it could be better.

At least in Linux a whole bunch of entropy sources get mixed
into the pool that can be accessed through /dev/random and /dev/urandom.
The only difference between those two devices is to my knowledge
that /dev/random has an entropy estimator which blocks access until it
thinks that sufficient entropy has been gathered. That's the thing that
should be used to have some confidence in the randomness

I have no idea what the equivalents on other platforms are or what
convenient way there is to get good random numbers across the platforms.

Regards,
Philipp

···

On Wed, 20 Nov 2013 21:20:02 +0200 Lyubomir Marinov <lyubomir.marinov@jitsi.org> wrote:

We're gather samples from the audio device (I don't know about the
merits of that entropy source) at the start of the application in
order to seed a random generator used by ZRTP and SDES. We're not
using that for DTLS-SRTP. Now you're talking about OTR. I guess we'd
better introduce an OSGi service in libjitsi and use that everywhere?


#8

We're gather samples from the audio device (I don't know about the
merits of that entropy source) at the start of the application in
order to seed a random generator used by ZRTP and SDES. We're not
using that for DTLS-SRTP. Now you're talking about OTR. I guess we'd
better introduce an OSGi service in libjitsi and use that everywhere?

Instead of an OSGi service we could implement SecureRandomSpi - and we
wouldn't need to care about libraries using SecureRandom anymore.

I assume you mean samples from the microphone?

Yes.

I'm far from an expert, but one possible problem is obvious: What if
the microphone is disabled when jitsi is started? Nothing but Zeros.
Chances are that I use this zero-seed, so I have to throw away my
jitsi config again.

Hmm. Good point.

I'm not sure how random the result is in the case of the enabled
microphone, but my guess is that it could be better.

It gets worse: in my dev-env it's zero, even with the microphone enabled! We
definitely need to fix this. And if reading from the sound device fails, it
is just silently ignored...
Now not all is lost for previous ZRTP/SDES calls because Fortuna is still
seeded with the defaults of java.util.Random(), but this is even worse than
/dev/urandom.

At least in Linux a whole bunch of entropy sources get mixed
into the pool that can be accessed through /dev/random and /dev/urandom.
The only difference between those two devices is to my knowledge
that /dev/random has an entropy estimator which blocks access until it
thinks that sufficient entropy has been gathered. That's the thing that
should be used to have some confidence in the randomness

The problem is that /dev/random is just too slow to be usable. It might be
feasible for an OTR key generation to wait a minute, but not for seeding the
crypto engines to start a call. And we're not talking about a lot of data
here - more like 44 bytes for SDES.

I have no idea what the equivalents on other platforms are or what
convenient way there is to get good random numbers across the platforms.

SecureRandom on Windows uses the CryptoAPI which should be reasonably secure
(and please no politics about closed source now).

Regards,
Philipp

Ingo


#9

>> We're gather samples from the audio device (I don't know about the
>> merits of that entropy source) at the start of the application in
>> order to seed a random generator used by ZRTP and SDES. We're not
>> using that for DTLS-SRTP. Now you're talking about OTR. I guess
>> we'd better introduce an OSGi service in libjitsi and use that
>> everywhere?

Instead of an OSGi service we could implement SecureRandomSpi - and we
wouldn't need to care about libraries using SecureRandom anymore.

> I assume you mean samples from the microphone?

Yes.

> I'm far from an expert, but one possible problem is obvious: What if
> the microphone is disabled when jitsi is started? Nothing but Zeros.
> Chances are that I use this zero-seed, so I have to throw away my
> jitsi config again.

Hmm. Good point.

> I'm not sure how random the result is in the case of the enabled
> microphone, but my guess is that it could be better.

It gets worse: in my dev-env it's zero, even with the microphone
enabled! We definitely need to fix this. And if reading from the
sound device fails, it is just silently ignored...
Now not all is lost for previous ZRTP/SDES calls because Fortuna is
still seeded with the defaults of java.util.Random(), but this is
even worse than /dev/urandom.

I did not look at the code at all, but can it be that some
processing like noise cancellation causes this?
But it's better to just fix it properly than to figure out what is
wrong there.

> At least in Linux a whole bunch of entropy sources get mixed
> into the pool that can be accessed through /dev/random
> and /dev/urandom. The only difference between those two devices is
> to my knowledge that /dev/random has an entropy estimator which
> blocks access until it thinks that sufficient entropy has been
> gathered. That's the thing that should be used to have some
> confidence in the randomness

The problem is that /dev/random is just too slow to be usable. It
might be feasible for an OTR key generation to wait a minute, but not
for seeding the crypto engines to start a call. And we're not talking
about a lot of data here - more like 44 bytes for SDES.

I think tests are in order here, for 44 bytes it might even be fast
enough.

> I have no idea what the equivalents on other platforms are or what
> convenient way there is to get good random numbers across the
> platforms.

SecureRandom on Windows uses the CryptoAPI which should be reasonably
secure (and please no politics about closed source now).

I only wonder whether CryptoAPI and its Apple-equivalent use RDRAND
exclusively. There has been some discussion about this in Linux-land.
It comes down to people not trusting a hardware PRNG. For this
reason /dev/random uses the hardware PRNG but uses other entropy
sources as well.
Apparently CryptoAPI does support the infamous Dual_EC_DRBG, I
wonder whether there's some good crypto library that avoids such
pitfalls.

Regards,
Philipp

···

On Wed, 20 Nov 2013 23:19:30 +0100 "Ingo Bauersachs" <ingo@jitsi.org> wrote:


#10

I did not look at the code at all, but can it be that some
processing like noise cancellation causes this?

Probably.

But it's better to just fix it properly than to figure out what is
wrong there.

Absolutely.

At least in Linux a whole bunch of entropy sources get mixed
into the pool that can be accessed through /dev/random
and /dev/urandom. The only difference between those two devices is
to my knowledge that /dev/random has an entropy estimator which
blocks access until it thinks that sufficient entropy has been
gathered. That's the thing that should be used to have some
confidence in the randomness

The problem is that /dev/random is just too slow to be usable. It
might be feasible for an OTR key generation to wait a minute, but not
for seeding the crypto engines to start a call. And we're not talking
about a lot of data here - more like 44 bytes for SDES.

I think tests are in order here, for 44 bytes it might even be fast
enough.

We actually had problems with massively delayed calls when just using
SecureRandom (which often goes to /dev/urandom by default).

I have no idea what the equivalents on other platforms are or what
convenient way there is to get good random numbers across the
platforms.

SecureRandom on Windows uses the CryptoAPI which should be reasonably
secure (and please no politics about closed source now).

I only wonder whether CryptoAPI and its Apple-equivalent use RDRAND
exclusively.

I doubt that because its only available from Ivy Bridge and newer CPUs.

There has been some discussion about this in Linux-land. It
comes down to people not trusting a hardware PRNG. For this reason
/dev/random uses the hardware PRNG but uses other entropy sources as
well. Apparently CryptoAPI does support the infamous Dual_EC_DRBG, I
wonder whether there's some good crypto library that avoids such
pitfalls.

Even if they solely use RDRAND in CryptoAPI, Java's default SecureRandom
implementation adds his own "system entropy" (current time, JVM system
properties, IP address, file names in the temp-dir, total memory size and
free memory). Somewhat predictable, but better than nothing.

Actually, I'm currently more concerned about our seeding of Fortuna than the
usage of SecureRandom for OTR key generation.

Regards,
Philipp

Ingo


#11

That's weird because /dev/urandom doesn't block by definition, so it
shouldn't cause any delay.
How long /dev/random blocks depends on the number of bits you need.
You can get an impression of that very easily: 'cat /dev/urandom' or
'cat /dev/random'.
Maybe the delay was caused by something SecureRandom does, it may also
have an entropy estimator that blocks, even if /dev/urandom is used as
one of the sources.

Regards,
Philipp

···

On Thu, 21 Nov 2013 09:31:28 +0100 "Ingo Bauersachs" <ingo@jitsi.org> wrote:

> I did not look at the code at all, but can it be that some
> processing like noise cancellation causes this?

Probably.

> But it's better to just fix it properly than to figure out what is
> wrong there.

Absolutely.

>>> At least in Linux a whole bunch of entropy sources get mixed
>>> into the pool that can be accessed through /dev/random
>>> and /dev/urandom. The only difference between those two devices is
>>> to my knowledge that /dev/random has an entropy estimator which
>>> blocks access until it thinks that sufficient entropy has been
>>> gathered. That's the thing that should be used to have some
>>> confidence in the randomness
>>
>> The problem is that /dev/random is just too slow to be usable. It
>> might be feasible for an OTR key generation to wait a minute, but
>> not for seeding the crypto engines to start a call. And we're not
>> talking about a lot of data here - more like 44 bytes for SDES.
>
> I think tests are in order here, for 44 bytes it might even be fast
> enough.

We actually had problems with massively delayed calls when just using
SecureRandom (which often goes to /dev/urandom by default).


#12

We actually had problems with massively delayed calls when just using
SecureRandom (which often goes to /dev/urandom by default).

That's weird because /dev/urandom doesn't block by definition, so it
shouldn't cause any delay.
How long /dev/random blocks depends on the number of bits you need.
You can get an impression of that very easily: 'cat /dev/urandom' or
'cat /dev/random'.
Maybe the delay was caused by something SecureRandom does, it may also
have an entropy estimator that blocks, even if /dev/urandom is used as
one of the sources.

Sorry, I confused the two. Should have been /dev/random.

Regards,
Philipp

Ingo