58 * Security property to a URL specifying the location of the entropy
59 * gathering device, or by setting the {@code java.security.egd} System
60 * property.
61 * <p>
62 * In the event the specified URL cannot be accessed the default
63 * threading mechanism is used.
64 *
65 * @author Joshua Bloch
66 * @author Gadi Guy
67 */
68
69 import java.security.*;
70 import java.io.*;
71 import java.util.Properties;
72 import java.util.Enumeration;
73 import java.net.*;
74 import java.nio.file.DirectoryStream;
75 import java.nio.file.Files;
76 import java.nio.file.Path;
77 import java.util.Random;
78 import sun.misc.ManagedLocalsThread;
79 import sun.security.util.Debug;
80
81 abstract class SeedGenerator {
82
83 // Static instance is created at link time
84 private static SeedGenerator instance;
85
86 private static final Debug debug = Debug.getInstance("provider");
87
88 // Static initializer to hook in selected or best performing generator
89 static {
90 String egdSource = SunEntries.getSeedSource();
91
92 /*
93 * Try the URL specifying the source (e.g. file:/dev/random)
94 *
95 * The URLs "file:/dev/random" or "file:/dev/urandom" are used to
96 * indicate the SeedGenerator should use OS support, if available.
97 *
98 * On Windows, this causes the MS CryptoAPI seeder to be used.
288
289 try {
290 digest = MessageDigest.getInstance("SHA");
291 } catch (NoSuchAlgorithmException e) {
292 throw new InternalError("internal error: SHA-1 not available."
293 , e);
294 }
295
296 final ThreadGroup[] finalsg = new ThreadGroup[1];
297 Thread t = java.security.AccessController.doPrivileged
298 (new java.security.PrivilegedAction<>() {
299 @Override
300 public Thread run() {
301 ThreadGroup parent, group =
302 Thread.currentThread().getThreadGroup();
303 while ((parent = group.getParent()) != null) {
304 group = parent;
305 }
306 finalsg[0] = new ThreadGroup
307 (group, "SeedGenerator ThreadGroup");
308 Thread newT = new ManagedLocalsThread(finalsg[0],
309 ThreadedSeedGenerator.this,
310 "SeedGenerator Thread");
311 newT.setPriority(Thread.MIN_PRIORITY);
312 newT.setDaemon(true);
313 return newT;
314 }
315 });
316 seedGroup = finalsg[0];
317 t.start();
318 }
319
320 /**
321 * This method does the actual work. It collects random bytes and
322 * pushes them into the queue.
323 */
324 @Override
325 public final void run() {
326 try {
327 while (true) {
328 // Queue full? Wait till there's room.
329 synchronized(this) {
330 while (count >= pool.length) {
331 wait();
332 }
333 }
334
335 int counter, quanta;
336 byte v = 0;
337
338 // Spin count must not be under 64000
339 for (counter = quanta = 0;
340 (counter < 64000) && (quanta < 6); quanta++) {
341
342 // Start some noisy threads
343 try {
344 BogusThread bt = new BogusThread();
345 Thread t = new ManagedLocalsThread
346 (seedGroup, bt, "SeedGenerator Thread");
347 t.start();
348 } catch (Exception e) {
349 throw new InternalError("internal error: " +
350 "SeedGenerator thread creation error.", e);
351 }
352
353 // We wait 250milli quanta, so the minimum wait time
354 // cannot be under 250milli.
355 int latch = 0;
356 long l = System.currentTimeMillis() + 250;
357 while (System.currentTimeMillis() < l) {
358 synchronized(this){};
359 latch++;
360 }
361
362 // Translate the value using the permutation, and xor
363 // it with previous values gathered.
364 v ^= rndTab[latch % 255];
365 counter += latch;
366 }
|
58 * Security property to a URL specifying the location of the entropy
59 * gathering device, or by setting the {@code java.security.egd} System
60 * property.
61 * <p>
62 * In the event the specified URL cannot be accessed the default
63 * threading mechanism is used.
64 *
65 * @author Joshua Bloch
66 * @author Gadi Guy
67 */
68
69 import java.security.*;
70 import java.io.*;
71 import java.util.Properties;
72 import java.util.Enumeration;
73 import java.net.*;
74 import java.nio.file.DirectoryStream;
75 import java.nio.file.Files;
76 import java.nio.file.Path;
77 import java.util.Random;
78 import sun.security.util.Debug;
79
80 abstract class SeedGenerator {
81
82 // Static instance is created at link time
83 private static SeedGenerator instance;
84
85 private static final Debug debug = Debug.getInstance("provider");
86
87 // Static initializer to hook in selected or best performing generator
88 static {
89 String egdSource = SunEntries.getSeedSource();
90
91 /*
92 * Try the URL specifying the source (e.g. file:/dev/random)
93 *
94 * The URLs "file:/dev/random" or "file:/dev/urandom" are used to
95 * indicate the SeedGenerator should use OS support, if available.
96 *
97 * On Windows, this causes the MS CryptoAPI seeder to be used.
287
288 try {
289 digest = MessageDigest.getInstance("SHA");
290 } catch (NoSuchAlgorithmException e) {
291 throw new InternalError("internal error: SHA-1 not available."
292 , e);
293 }
294
295 final ThreadGroup[] finalsg = new ThreadGroup[1];
296 Thread t = java.security.AccessController.doPrivileged
297 (new java.security.PrivilegedAction<>() {
298 @Override
299 public Thread run() {
300 ThreadGroup parent, group =
301 Thread.currentThread().getThreadGroup();
302 while ((parent = group.getParent()) != null) {
303 group = parent;
304 }
305 finalsg[0] = new ThreadGroup
306 (group, "SeedGenerator ThreadGroup");
307 Thread newT = new Thread(finalsg[0],
308 ThreadedSeedGenerator.this,
309 "SeedGenerator Thread",
310 0,
311 false);
312 newT.setPriority(Thread.MIN_PRIORITY);
313 newT.setDaemon(true);
314 return newT;
315 }
316 });
317 seedGroup = finalsg[0];
318 t.start();
319 }
320
321 /**
322 * This method does the actual work. It collects random bytes and
323 * pushes them into the queue.
324 */
325 @Override
326 public final void run() {
327 try {
328 while (true) {
329 // Queue full? Wait till there's room.
330 synchronized(this) {
331 while (count >= pool.length) {
332 wait();
333 }
334 }
335
336 int counter, quanta;
337 byte v = 0;
338
339 // Spin count must not be under 64000
340 for (counter = quanta = 0;
341 (counter < 64000) && (quanta < 6); quanta++) {
342
343 // Start some noisy threads
344 try {
345 BogusThread bt = new BogusThread();
346 Thread t = new Thread
347 (seedGroup, bt, "SeedGenerator Thread", 0, false);
348 t.start();
349 } catch (Exception e) {
350 throw new InternalError("internal error: " +
351 "SeedGenerator thread creation error.", e);
352 }
353
354 // We wait 250milli quanta, so the minimum wait time
355 // cannot be under 250milli.
356 int latch = 0;
357 long l = System.currentTimeMillis() + 250;
358 while (System.currentTimeMillis() < l) {
359 synchronized(this){};
360 latch++;
361 }
362
363 // Translate the value using the permutation, and xor
364 // it with previous values gathered.
365 v ^= rndTab[latch % 255];
366 counter += latch;
367 }
|