forked from I2P_Developers/i2p.i2p
Merge branch 'devrandom' into 'master'
PRNG: Switch to /dev/random by default See merge request i2p-hackers/i2p.i2p!238
This commit is contained in:
@ -40,14 +40,13 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
|
||||
private AsyncBuffer _currentBuffer;
|
||||
|
||||
public AsyncFortunaStandalone(I2PAppContext context) {
|
||||
super(context.getBooleanProperty("prng.useDevRandom") && !SystemVersion.isWindows() && !SystemVersion.isSlow());
|
||||
super(context.getBooleanPropertyDefaultTrue("prng.useDevRandom") && !SystemVersion.isWindows() && !SystemVersion.isSlow());
|
||||
_bufferCount = Math.max(context.getProperty("prng.buffers", DEFAULT_BUFFERS), 2);
|
||||
_bufferSize = Math.max(context.getProperty("prng.bufferSize", DEFAULT_BUFSIZE), 16*1024);
|
||||
_emptyBuffers = new LinkedBlockingQueue<AsyncBuffer>(_bufferCount);
|
||||
_fullBuffers = new LinkedBlockingQueue<AsyncBuffer>(_bufferCount);
|
||||
_context = context;
|
||||
context.statManager().createRateStat("prng.bufferWaitTime", "Delay for random number buffer (ms)", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } );
|
||||
context.statManager().createRateStat("prng.bufferFillTime", "Time to fill random number buffer (ms)", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } );
|
||||
context.statManager().createRateStat("prng.bufferFillTime", "Time to fill random number buffer (ms)", "Encryption", new long[] { 60*60*1000 } );
|
||||
_log = context.logManager().getLog(AsyncFortunaStandalone.class);
|
||||
}
|
||||
|
||||
@ -80,12 +79,8 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
|
||||
public void seed(byte val[]) {
|
||||
Map<String, byte[]> props = Collections.singletonMap(SEED, val);
|
||||
init(props);
|
||||
//fillBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void allocBuffer() {}
|
||||
|
||||
private static class AsyncBuffer {
|
||||
public final byte[] buffer;
|
||||
|
||||
@ -103,7 +98,6 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
|
||||
AsyncBuffer old = _currentBuffer;
|
||||
if (old != null)
|
||||
_emptyBuffers.offer(old);
|
||||
long before = System.currentTimeMillis();
|
||||
AsyncBuffer nextBuffer = null;
|
||||
|
||||
while (nextBuffer == null) {
|
||||
@ -115,11 +109,6 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
|
||||
continue;
|
||||
}
|
||||
}
|
||||
long waited = System.currentTimeMillis()-before;
|
||||
_context.statManager().addRateData("prng.bufferWaitTime", waited, 0);
|
||||
if (waited > 10*1000 && _log.shouldLog(Log.WARN))
|
||||
_log.warn(Thread.currentThread().getName() + ": Took " + waited
|
||||
+ "ms for a full PRNG buffer to be found");
|
||||
_currentBuffer = nextBuffer;
|
||||
buffer = nextBuffer.buffer;
|
||||
}
|
||||
@ -162,26 +151,22 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
|
||||
}
|
||||
|
||||
private void doFill(byte buf[]) {
|
||||
//long start = System.currentTimeMillis();
|
||||
if (pool0Count >= MIN_POOL_SIZE
|
||||
&& System.currentTimeMillis() - lastReseed > 100)
|
||||
{
|
||||
reseedCount++;
|
||||
//byte[] seed = new byte[0];
|
||||
for (int i = 0; i < NUM_POOLS; i++)
|
||||
if (pools != null) {
|
||||
if (pool0Count >= MIN_POOL_SIZE
|
||||
&& System.currentTimeMillis() - lastReseed > 100)
|
||||
{
|
||||
if (reseedCount % (1 << i) == 0) {
|
||||
generator.addRandomBytes(pools[i].digest());
|
||||
}
|
||||
reseedCount++;
|
||||
//byte[] seed = new byte[0];
|
||||
for (int i = 0; i < NUM_POOLS; i++)
|
||||
{
|
||||
if (reseedCount % (1 << i) == 0) {
|
||||
generator.addRandomBytes(pools[i].digest());
|
||||
}
|
||||
}
|
||||
lastReseed = System.currentTimeMillis();
|
||||
}
|
||||
lastReseed = System.currentTimeMillis();
|
||||
}
|
||||
} // else we're using DevRandom
|
||||
generator.nextBytes(buf);
|
||||
//long now = System.currentTimeMillis();
|
||||
//long diff = now-lastRefill;
|
||||
//lastRefill = now;
|
||||
//long refillTime = now-start;
|
||||
//System.out.println("Refilling " + (++refillCount) + " after " + diff + " for the PRNG took " + refillTime);
|
||||
}
|
||||
|
||||
/*****
|
||||
|
@ -18,10 +18,17 @@ class DevRandom implements IRandomStandalone {
|
||||
private static final String F = "/dev/random";
|
||||
private final File file = new File(F);
|
||||
|
||||
/**
|
||||
* @since 0.9.66
|
||||
*/
|
||||
public static boolean isSupported() {
|
||||
return (new File(F)).canRead();
|
||||
}
|
||||
|
||||
public String name() { return F; }
|
||||
|
||||
public void init(Map<String, byte[]> attributes) {
|
||||
if (!file.canRead())
|
||||
if (!isSupported())
|
||||
throw new IllegalStateException("Cannot open " + F);
|
||||
}
|
||||
|
||||
@ -29,9 +36,6 @@ class DevRandom implements IRandomStandalone {
|
||||
throw new IllegalStateException("unsupported");
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.58 added to interface
|
||||
*/
|
||||
public void nextBytes(byte[] out) throws IllegalStateException {
|
||||
nextBytes(out, 0, out.length);
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ import java.io.Serializable;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.crypto.CryptixAESKeyCache;
|
||||
@ -104,6 +103,7 @@ public class FortunaStandalone extends BasePRNGStandalone implements Serializabl
|
||||
static final int NUM_POOLS = 32;
|
||||
static final int MIN_POOL_SIZE = 64;
|
||||
protected final IRandomStandalone generator;
|
||||
/** null if using DevRandom */
|
||||
protected final MessageDigest[] pools;
|
||||
protected long lastReseed;
|
||||
private int pool;
|
||||
@ -121,23 +121,22 @@ public class FortunaStandalone extends BasePRNGStandalone implements Serializabl
|
||||
*/
|
||||
public FortunaStandalone(boolean useDevRandom) {
|
||||
super("Fortuna i2p");
|
||||
if (useDevRandom && !DevRandom.isSupported())
|
||||
useDevRandom = false;
|
||||
generator = useDevRandom ? new DevRandom() : new Generator();
|
||||
pools = new MessageDigest[NUM_POOLS];
|
||||
for (int i = 0; i < NUM_POOLS; i++)
|
||||
pools[i] = SHA256Generator.getDigestInstance();
|
||||
allocBuffer();
|
||||
}
|
||||
|
||||
/** Unused, see AsyncFortunaStandalone */
|
||||
protected void allocBuffer() {
|
||||
buffer = new byte[64*1024];
|
||||
if (useDevRandom) {
|
||||
pools = null;
|
||||
} else {
|
||||
pools = new MessageDigest[NUM_POOLS];
|
||||
for (int i = 0; i < NUM_POOLS; i++) {
|
||||
pools[i] = SHA256Generator.getDigestInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Unused, see AsyncFortunaStandalone */
|
||||
public void seed(byte val[]) {
|
||||
Map<String, byte[]> props = Collections.singletonMap(SEED, val);
|
||||
init(props);
|
||||
fillBlock();
|
||||
throw new UnsupportedOperationException("use override");
|
||||
}
|
||||
|
||||
public void setup(Map<String, byte[]> attributes)
|
||||
@ -152,31 +151,14 @@ public class FortunaStandalone extends BasePRNGStandalone implements Serializabl
|
||||
/** Unused, see AsyncFortunaStandalone */
|
||||
public void fillBlock()
|
||||
{
|
||||
//long start = System.currentTimeMillis();
|
||||
if (pool0Count >= MIN_POOL_SIZE
|
||||
&& System.currentTimeMillis() - lastReseed > 100)
|
||||
{
|
||||
reseedCount++;
|
||||
//byte[] seed = new byte[0];
|
||||
for (int i = 0; i < NUM_POOLS; i++)
|
||||
{
|
||||
if (reseedCount % (1 << i) == 0) {
|
||||
generator.addRandomBytes(pools[i].digest());
|
||||
}
|
||||
}
|
||||
lastReseed = System.currentTimeMillis();
|
||||
}
|
||||
generator.nextBytes(buffer);
|
||||
//long now = System.currentTimeMillis();
|
||||
//long diff = now-lastRefill;
|
||||
//lastRefill = now;
|
||||
//long refillTime = now-start;
|
||||
//System.out.println("Refilling " + (++refillCount) + " after " + diff + " for the PRNG took " + refillTime);
|
||||
throw new UnsupportedOperationException("use override");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRandomByte(byte b)
|
||||
{
|
||||
if (pools == null)
|
||||
return;
|
||||
pools[pool].update(b);
|
||||
if (pool == 0)
|
||||
pool0Count++;
|
||||
@ -186,6 +168,8 @@ public class FortunaStandalone extends BasePRNGStandalone implements Serializabl
|
||||
@Override
|
||||
public void addRandomBytes(byte[] buf, int offset, int length)
|
||||
{
|
||||
if (pools == null)
|
||||
return;
|
||||
pools[pool].update(buf, offset, length);
|
||||
if (pool == 0)
|
||||
pool0Count += length;
|
||||
|
@ -170,7 +170,7 @@ public class RouterContext extends I2PAppContext {
|
||||
// or about 2 seconds per buffer - so about 200x faster
|
||||
// to fill than to drain - so we don't need too many
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
long maxBuffs = (SystemVersion.isAndroid() || SystemVersion.isARM()) ? 3 : 5;
|
||||
long maxBuffs = 3;
|
||||
long buffs = Math.min(maxBuffs, Math.max(2, maxMemory / (21 * 1024 * 1024)));
|
||||
envProps.setProperty("prng.buffers", Long.toString(buffs));
|
||||
}
|
||||
|
Reference in New Issue
Block a user