Use new PRNG and implement entropy gathering and seeding

This patch updates the zrtp4j and the lightweight crypto libraries.
Both libraries implement and use the Fortuna PRNG that create high
quality random data.
The new GatherEntropy class implements methods to gather random data
from media capture devices and use this data as entropy to seed the
Fortuna PRNG. This enhance the quality of random data.
This works with portaudio, JMF audio not yet supported, video may be
added at a later time.
cusax-fix
Werner Dittmann 16 years ago
parent 7b39a3d556
commit 3b104813e3

@ -2234,6 +2234,7 @@ org.apache.http.util"/>
org.bouncycastle.crypto.digests,
org.bouncycastle.crypto.macs,
org.bouncycastle.crypto.params,
org.bouncycastle.crypto.prng,
org.bouncycastle.crypto.engines,
org.bouncycastle.crypto.modes"/>
<attribute name="Bundle-Name" value="ZRTP4J"/>
@ -2275,6 +2276,7 @@ org.apache.http.util"/>
org.bouncycastle.crypto.digests,
org.bouncycastle.crypto.macs,
org.bouncycastle.crypto.params,
org.bouncycastle.crypto.prng,
org.bouncycastle.crypto.engines,
org.bouncycastle.crypto.modes,
org.bouncycastle.crypto.generators,

@ -0,0 +1,138 @@
package net.java.sip.communicator.impl.neomedia;
import javax.media.*;
import gnu.java.zrtp.utils.*;
import net.java.sip.communicator.impl.neomedia.device.*;
import net.java.sip.communicator.impl.neomedia.portaudio.*;
import net.java.sip.communicator.impl.neomedia.portaudio.streams.*;
/**
* GatherEntropy initializes the Fortuna PRNG with entropy data.
*
* GatherEntropy gets the media device configuration and checks which media
* systems are available. It then reads some data fom media input (capture)
* devices and uses this data to seed the Fortuna PRNG. The ZrtpFortuna PRNG
* is a singleton and all other methods that require random data shall use
* this singleton.
*
* Use GatherEntropy during startup and initialization phase of SIP
* Communicator but after initialization of the media devices to get entropy
* data at the earliest point. Also make sure that entropy data is read from
* local sources only and that entropy data is never send out (via networks
* for example).
*
* TODO: add JMF method to read audio (mic) data, check if we can use video?
*
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*
*/
public class GatherEntropy {
/**
* Device config to look for catpture devices.
*/
private DeviceConfiguration deviceConfiguration;
public GatherEntropy(DeviceConfiguration deviceConfiguration)
{
this.deviceConfiguration = deviceConfiguration;
}
/**
* Set entropy to ZrtpFortuna singleton.
*
* The methods reads entropy data and seeds the ZrtpFortuna singleton.
* The methods seeds the first pool (0) of Fortuna to make sure that
* this entropy is always used.
*
* @return true if entropy data was available, false otherwise.
*/
public boolean setEntropy()
{
boolean retValue = false;
ZrtpFortuna fortuna = ZrtpFortuna.getInstance();
byte entropy[] = readAudioEntropy();
if (entropy != null) {
fortuna.addSeedMaterial(0, entropy, 0, entropy.length);
retValue = true;
}
return retValue;
}
/**
* Read entropy data from audio capture device.
*
* The method checks which audio systems are available and calls the
* appropriate method the get some random data.
*
* @return Audio data from capture (microphone) device or null if
* no data was available.
*
*/
private byte[] readAudioEntropy()
{
try
{
if(deviceConfiguration.getAudioSystem().equals(
DeviceConfiguration.AUDIO_SYSTEM_JAVASOUND))
{
// return readJMFAudioEntropy();
}
else if(deviceConfiguration.getAudioSystem().equals(
DeviceConfiguration.AUDIO_SYSTEM_PORTAUDIO))
{
return readPortAudioEntropy();
}
else
return null;
}
catch (Throwable e)
{
// Cannot create audio to read entropy
return null;
}
return null;
}
/**
* Read entropy data from portaudio capture device.
*
* The method reads audio samples from the microphone, combines them and
* returns the data.
*
* @return Audio data from capture (microphone) device or null if no data
* was available.
*
* @throws PortAudioException
*/
private byte[] readPortAudioEntropy() throws PortAudioException
{
int deviceIndex = PortAudioUtils
.getDeviceIndexFromLocator(deviceConfiguration
.getAudioCaptureDevice().getLocator());
InputPortAudioStream portAudioStream = PortAudioManager.getInstance()
.getInputStream(deviceIndex, 8000.0, 1);
Buffer firstBuf = new Buffer();
Buffer secondBuf = new Buffer();
portAudioStream.start();
portAudioStream.read(firstBuf);
portAudioStream.read(secondBuf);
portAudioStream.stop();
// make sure we have enough data
int length = firstBuf.getLength() + secondBuf.getLength();
if (length < 64) {
return null;
}
byte[] returnData = new byte[length];
System.arraycopy(firstBuf.getData(), 0, returnData, 0, firstBuf.getLength());
System.arraycopy(secondBuf.getData(), 0, returnData, firstBuf.getLength(), secondBuf.getLength());
return returnData;
}
}

@ -134,6 +134,9 @@ public void start(BundleContext bundleContext)
1100),
null);
GatherEntropy entropy = new GatherEntropy(mediaServiceImpl.getDeviceConfiguration());
entropy.setEntropy();
//we use the nist-sdp stack to make parse sdp and we need to set the
//following property to make sure that it would accept java generated
//IPv6 addresses that contain address scope zones.

@ -10,6 +10,7 @@ Import-Package: org.osgi.framework,
org.bouncycastle.crypto.digests,
org.bouncycastle.crypto.macs,
org.bouncycastle.crypto.params,
org.bouncycastle.crypto.prng,
org.bouncycastle.crypto.engines,
javax.imageio,
javax.sound.sampled,

Loading…
Cancel
Save