From 896af2c5d2cf4a39dd61d2c1b694910b201e1c3f Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sat, 25 Jun 2016 22:20:27 +0000
Subject: [PATCH] Utils: Improve random seed initialization Fallback to Random
 rather than try SecureRandom twice Fetch from SecureRandom incrementally
 Remove log warning

---
 .../src/net/i2p/util/FortunaRandomSource.java |  5 ++++-
 core/java/src/net/i2p/util/RandomSource.java  | 19 +++++++++++++------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/core/java/src/net/i2p/util/FortunaRandomSource.java b/core/java/src/net/i2p/util/FortunaRandomSource.java
index 606a6cd233..508bac7e17 100644
--- a/core/java/src/net/i2p/util/FortunaRandomSource.java
+++ b/core/java/src/net/i2p/util/FortunaRandomSource.java
@@ -13,6 +13,7 @@ import gnu.crypto.prng.AsyncFortunaStandalone;
 
 import java.io.IOException;
 import java.security.SecureRandom;
+import java.util.Random;
 
 import net.i2p.I2PAppContext;
 import net.i2p.crypto.EntropyHarvester;
@@ -40,7 +41,9 @@ public class FortunaRandomSource extends RandomSource implements EntropyHarveste
             _fortuna.seed(seed);
         } else {
             // may block forever
-            SecureRandom sr = new SecureRandom();
+            //SecureRandom sr = new SecureRandom();
+            // SecureRandom already failed in initSeed(), so try Random
+            Random sr = new Random();
             sr.nextBytes(seed);
             _fortuna.seed(seed);
         }
diff --git a/core/java/src/net/i2p/util/RandomSource.java b/core/java/src/net/i2p/util/RandomSource.java
index b92295e633..04e457a08a 100644
--- a/core/java/src/net/i2p/util/RandomSource.java
+++ b/core/java/src/net/i2p/util/RandomSource.java
@@ -195,8 +195,9 @@ public class RandomSource extends SecureRandom implements EntropyHarvester {
                 }
                 if (ok)
                     System.arraycopy(tbuf, 0, buf, 0, buf.length);
-                else
-                    System.out.println("INFO: SecureRandom init failed or took too long");
+                // See FortunaRandomSource constructor for fallback
+                //else
+                //    System.out.println("INFO: SecureRandom init failed or took too long");
             }
         } catch (InterruptedException ie) {}
 
@@ -218,17 +219,23 @@ public class RandomSource extends SecureRandom implements EntropyHarvester {
      */
     private static class SecureRandomInit implements Runnable {
         private final byte[] buf;
+        private static final int SZ = 64;
 
         public SecureRandomInit(byte[] buf) {
             this.buf = buf;
         }
 
         public void run() {
-            byte[] buf2 = new byte[buf.length];
+            byte[] buf2 = new byte[SZ];
+            // do this 64 bytes at a time, so if system is low on entropy we will
+            // hopefully get something before the timeout
             try {
-                SecureRandom.getInstance("SHA1PRNG").nextBytes(buf2);
-                synchronized(buf) {
-                    System.arraycopy(buf2, 0, buf, 0, buf.length);
+                SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
+                for (int i = 0; i < buf.length; i += SZ) {
+                    sr.nextBytes(buf2);
+                    synchronized(buf) {
+                        System.arraycopy(buf2, 0, buf, i, Math.min(SZ, buf.length - i));
+                    }
                 }
             } catch (NoSuchAlgorithmException e) {}
         }
-- 
GitLab