Util: Add experimental config to bypass Fortuna and just use /dev/random

Refactor Fortuna so it may be extended
Reduce default buf size for Android
This commit is contained in:
zzz
2023-01-30 14:04:50 -05:00
parent 4ef4ae4df5
commit 665e63da5b
4 changed files with 82 additions and 18 deletions

View File

@@ -7,6 +7,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import net.i2p.I2PAppContext;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.SystemVersion;
/**
* fortuna instance that tries to avoid blocking if at all possible by using separate
@@ -25,7 +26,7 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
* The router must override this via the prng.buffers property in the router context.
*/
private static final int DEFAULT_BUFFERS = 2;
private static final int DEFAULT_BUFSIZE = 256*1024;
private static final int DEFAULT_BUFSIZE = SystemVersion.isAndroid() ? 64*1024 : 256*1024;
private final int _bufferCount;
private final int _bufferSize;
/** the lock */
@@ -39,7 +40,7 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl
private AsyncBuffer _currentBuffer;
public AsyncFortunaStandalone(I2PAppContext context) {
super();
super(context.getBooleanProperty("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);

View File

@@ -0,0 +1,57 @@
package gnu.crypto.prng;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Map;
import net.i2p.data.DataHelper;
/**
* Simple /dev/random reader
*
* @since 0.9.58
*/
class DevRandom implements IRandomStandalone {
private static final String F = "/dev/random";
private final File file = new File(F);
public String name() { return F; }
public void init(Map<String, byte[]> attributes) {
if (!file.canRead())
throw new IllegalStateException("Cannot open " + F);
}
public byte nextByte() {
throw new IllegalStateException("unsupported");
}
/**
* @since 0.9.58 added to interface
*/
public void nextBytes(byte[] out) throws IllegalStateException {
nextBytes(out, 0, out.length);
}
public void nextBytes(byte[] out, int offset, int length) throws IllegalStateException {
InputStream in = null;
try {
in = new FileInputStream(file);
DataHelper.read(in, out, offset, length);
} catch (IOException ioe) {
throw new IllegalStateException("Read failed " + F, ioe);
} finally {
if (in != null) try { in.close(); } catch (IOException ioe2) {}
}
}
public void addRandomByte(byte b) {}
public void addRandomBytes(byte[] in) {}
public void addRandomBytes(byte[] in, int offset, int length) {}
@Override
public Object clone() throws CloneNotSupportedException { return super.clone(); }
}

View File

@@ -103,33 +103,34 @@ public class FortunaStandalone extends BasePRNGStandalone implements Serializabl
private static final int SEED_FILE_SIZE = 64;
static final int NUM_POOLS = 32;
static final int MIN_POOL_SIZE = 64;
final Generator generator;
final MessageDigest[] pools;
long lastReseed;
int pool;
int pool0Count;
int reseedCount;
//static long refillCount = 0;
//static long lastRefill = System.currentTimeMillis();
protected final IRandomStandalone generator;
protected final MessageDigest[] pools;
protected long lastReseed;
private int pool;
protected int pool0Count;
protected int reseedCount;
public static final String SEED = "gnu.crypto.prng.fortuna.seed";
public FortunaStandalone()
{
public FortunaStandalone() {
this(false);
}
/**
* @since 0.9.58
*/
public FortunaStandalone(boolean useDevRandom) {
super("Fortuna i2p");
generator = new Generator();
generator = useDevRandom ? new DevRandom() : new Generator();
pools = new MessageDigest[NUM_POOLS];
for (int i = 0; i < NUM_POOLS; i++)
pools[i] = SHA256Generator.getDigestInstance();
lastReseed = 0;
pool = 0;
pool0Count = 0;
allocBuffer();
}
/** Unused, see AsyncFortunaStandalone */
protected void allocBuffer() {
buffer = new byte[4*1024*1024]; //256]; // larger buffer to reduce churn
buffer = new byte[64*1024];
}
/** Unused, see AsyncFortunaStandalone */
@@ -213,7 +214,7 @@ public class FortunaStandalone extends BasePRNGStandalone implements Serializabl
* right; Fortuna itself is basically a wrapper around this generator
* that manages reseeding in a secure way.
*/
public static class Generator extends BasePRNGStandalone implements Cloneable
private static class Generator extends BasePRNGStandalone implements Cloneable
{
private static final int LIMIT = 1 << 20;

View File

@@ -118,6 +118,11 @@ public interface IRandomStandalone extends Cloneable {
*/
byte nextByte() throws IllegalStateException;
/**
* @since 0.9.58 added to interface
*/
public void nextBytes(byte[] out) throws IllegalStateException;
/**
* <p>Fills the designated byte array, starting from byte at index
* <code>offset</code>, for a maximum of <code>length</code> bytes with the